diff --git a/apps/web/src/routes/internal.ts b/apps/web/src/routes/internal.ts index 2834e31..0b150c0 100644 --- a/apps/web/src/routes/internal.ts +++ b/apps/web/src/routes/internal.ts @@ -22,11 +22,15 @@ export const internal = new Elysia({ prefix: "/internal", detail: { hide: true } return {}; }) - // Returns monitors that are due for a check, with scheduled_at = now() + // Returns monitors that are due for a check. + // scheduled_at = last_checked_at + interval_s (ideal fire time), so jitter = actual_start - scheduled_at .get("/due", async () => { - const scheduled_at = new Date().toISOString(); const monitors = await sql` - SELECT m.id, m.url, m.method, m.request_headers, m.request_body, m.timeout_ms, m.interval_s, m.query + SELECT m.id, m.url, m.method, m.request_headers, m.request_body, m.timeout_ms, m.interval_s, m.query, + CASE + WHEN last.checked_at IS NULL THEN now() + ELSE last.checked_at + (m.interval_s || ' seconds')::interval + END AS scheduled_at FROM monitors m LEFT JOIN LATERAL ( SELECT checked_at FROM pings @@ -37,8 +41,7 @@ export const internal = new Elysia({ prefix: "/internal", detail: { hide: true } AND (last.checked_at IS NULL OR last.checked_at < now() - (m.interval_s || ' seconds')::interval) `; - // Attach scheduled_at to each monitor so the runner can report jitter - return monitors.map((m: any) => ({ ...m, scheduled_at })); + return monitors; }) // Manual retention cleanup trigger