From 4bf8d1b20dfab8d4b07c837b4e5bbd34cd8cab41 Mon Sep 17 00:00:00 2001 From: nate Date: Thu, 9 Apr 2026 03:44:57 +0400 Subject: [PATCH] fix: improve state management --- apps/api/src/routes/internal.ts | 53 +++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/apps/api/src/routes/internal.ts b/apps/api/src/routes/internal.ts index 17d55c4..c6f13b2 100644 --- a/apps/api/src/routes/internal.ts +++ b/apps/api/src/routes/internal.ts @@ -29,35 +29,42 @@ export const internal = new Elysia({ prefix: "/internal", detail: { hide: true } .get("/due", async ({ request }) => { const params = new URL(request.url).searchParams; - const region = params.get('region') || undefined; + const region = params.get('region') || 'default'; const lookaheadMs = Math.min(Number(params.get('lookahead_ms') || 2000), 10000); + // No JOIN, no state lookup. The check schedule for a monitor is purely + // a function of its created_at and interval_s — every interval since + // creation is a tick. We pull all enabled monitors that match this + // region, compute the next tick in JS, and return the ones whose next + // tick falls within the lookahead window. 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, m.regions, - m.max_retries, m.retry_interval_s, - EXTRACT(EPOCH FROM ( - CASE - WHEN last.checked_at IS NULL THEN now() - ELSE last.checked_at + (m.interval_s || ' seconds')::interval - END - ))::bigint * 1000 AS scheduled_at_ms - FROM monitors m - LEFT JOIN LATERAL ( - SELECT checked_at FROM pings - WHERE monitor_id = m.id - AND (${region ? sql`region = ${region}` : sql`true`}) - ORDER BY checked_at DESC LIMIT 1 - ) last ON true - WHERE m.enabled = true - AND (last.checked_at IS NULL - OR last.checked_at < now() - (m.interval_s || ' seconds')::interval + (${lookaheadMs} || ' milliseconds')::interval) + SELECT id, url, method, request_headers, request_body, timeout_ms, interval_s, query, regions, + max_retries, retry_interval_s, created_at + FROM monitors + WHERE enabled = true AND ( - array_length(m.regions, 1) IS NULL - OR m.regions = '{}' - OR ${region ? sql`${region} = ANY(m.regions)` : sql`true`} + array_length(regions, 1) IS NULL + OR regions = '{}' + OR ${region} = ANY(regions) ) + LIMIT 500 `; - return monitors; + + const nowMs = Date.now(); + const lookaheadEnd = nowMs + lookaheadMs; + const due: any[] = []; + for (const m of monitors) { + const createdMs = new Date((m as any).created_at).getTime(); + const intervalMs = Number((m as any).interval_s) * 1000; + if (intervalMs <= 0) continue; + const elapsed = nowMs - createdMs; + const ticksPassed = Math.floor(elapsed / intervalMs); + const nextTickMs = createdMs + (ticksPassed + 1) * intervalMs; + if (nextTickMs <= lookaheadEnd) { + due.push({ ...m, scheduled_at_ms: nextTickMs }); + } + } + return due; }) .post("/prune", async () => {