mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-13 20:46:39 +00:00
fix(cron): prevent spin loop when job completes within scheduled second (#17821)
When a cron job fires and completes within the same wall-clock second it was scheduled for, the next-run computation could return undefined or the same second, causing the scheduler to re-trigger the job hundreds of times in a tight loop. Two-layer fix: 1. computeJobNextRunAtMs: When computeNextRunAtMs returns undefined for a cron-kind schedule (edge case where floored nowSecondMs matches the schedule), retry with the ceiling (next second) as reference time. This ensures we always get the next valid occurrence. 2. applyJobResult: Add MIN_REFIRE_GAP_MS (2s) safety net for cron-kind jobs. After a successful run, nextRunAtMs is guaranteed to be at least 2s in the future. This breaks any remaining spin-loop edge cases without affecting normal daily/hourly schedules (where the natural next run is hours/days away). Fixes #17821
This commit is contained in:
committed by
Peter Steinberger
parent
eed806ce58
commit
8af4712c40
@@ -96,7 +96,18 @@ export function computeJobNextRunAtMs(job: CronJob, nowMs: number): number | und
|
||||
: null;
|
||||
return atMs !== null ? atMs : undefined;
|
||||
}
|
||||
return computeNextRunAtMs(job.schedule, nowMs);
|
||||
const next = computeNextRunAtMs(job.schedule, nowMs);
|
||||
// Guard against the scheduler returning a time within the same second as
|
||||
// nowMs. When a cron job completes within the same wall-clock second it
|
||||
// was scheduled for, some croner versions/timezone combinations may return
|
||||
// the current second (or computeNextRunAtMs may return undefined, which
|
||||
// triggers recomputation). Advancing to the next second and retrying
|
||||
// ensures we always land on the *next* occurrence. (See #17821)
|
||||
if (next === undefined && job.schedule.kind === "cron") {
|
||||
const nextSecondMs = (Math.floor(nowMs / 1000) + 1) * 1000;
|
||||
return computeNextRunAtMs(job.schedule, nextSecondMs);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
/** Maximum consecutive schedule errors before auto-disabling a job. */
|
||||
|
||||
Reference in New Issue
Block a user