fix(cron): prevent every schedule from firing in infinite loop

When anchorMs is not provided (always in production), the schedule
computed nextRunAtMs as nowMs, causing jobs to fire immediately and
repeatedly instead of at the configured interval.

- Change nowMs <= anchor to nowMs < anchor to prevent early return
- Add Math.max(1, ...) to ensure steps is always at least 1
- Add test for anchorMs not provided case
This commit is contained in:
James Groat
2026-01-01 17:27:43 -07:00
parent 9180cbe821
commit 7154bc6857
2 changed files with 10 additions and 2 deletions

View File

@@ -12,9 +12,9 @@ export function computeNextRunAtMs(
if (schedule.kind === "every") {
const everyMs = Math.max(1, Math.floor(schedule.everyMs));
const anchor = Math.max(0, Math.floor(schedule.anchorMs ?? nowMs));
if (nowMs <= anchor) return anchor;
if (nowMs < anchor) return anchor;
const elapsed = nowMs - anchor;
const steps = Math.floor((elapsed + everyMs - 1) / everyMs);
const steps = Math.max(1, Math.floor((elapsed + everyMs - 1) / everyMs));
return anchor + steps * everyMs;
}