fix: improve state management

This commit is contained in:
nate 2026-04-09 03:44:57 +04:00
parent 27d8630611
commit 4bf8d1b20d
1 changed files with 30 additions and 23 deletions

View File

@ -29,35 +29,42 @@ export const internal = new Elysia({ prefix: "/internal", detail: { hide: true }
.get("/due", async ({ request }) => { .get("/due", async ({ request }) => {
const params = new URL(request.url).searchParams; 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); 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` 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, SELECT id, url, method, request_headers, request_body, timeout_ms, interval_s, query, regions,
m.max_retries, m.retry_interval_s, max_retries, retry_interval_s, created_at
EXTRACT(EPOCH FROM ( FROM monitors
CASE WHERE enabled = true
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)
AND ( AND (
array_length(m.regions, 1) IS NULL array_length(regions, 1) IS NULL
OR m.regions = '{}' OR regions = '{}'
OR ${region ? sql`${region} = ANY(m.regions)` : sql`true`} 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 () => { .post("/prune", async () => {