mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 00:03:28 +00:00
fix(cron): prevent recomputeNextRuns from skipping due jobs in onTimer (#9823)
* fix(cron): prevent recomputeNextRuns from skipping due jobs in onTimer ensureLoaded(forceReload) called recomputeNextRuns before runDueJobs, which recalculated nextRunAtMs to a strictly future time. Since setTimeout always fires a few ms late, the due check (now >= nextRunAtMs) always failed and every/cron jobs never executed. Fixes #9788. * docs: add changelog entry for cron timer race fix (#9823) (thanks @pycckuu) --------- Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
This commit is contained in:
@@ -126,7 +126,15 @@ async function getFileMtimeMs(path: string): Promise<number | null> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureLoaded(state: CronServiceState, opts?: { forceReload?: boolean }) {
|
||||
export async function ensureLoaded(
|
||||
state: CronServiceState,
|
||||
opts?: {
|
||||
forceReload?: boolean;
|
||||
/** Skip recomputing nextRunAtMs after load so the caller can run due
|
||||
* jobs against the persisted values first (see onTimer). */
|
||||
skipRecompute?: boolean;
|
||||
},
|
||||
) {
|
||||
// Fast path: store is already in memory. Other callers (add, list, run, …)
|
||||
// trust the in-memory copy to avoid a stat syscall on every operation.
|
||||
if (state.store && !opts?.forceReload) {
|
||||
@@ -255,8 +263,9 @@ export async function ensureLoaded(state: CronServiceState, opts?: { forceReload
|
||||
state.storeLoadedAtMs = state.deps.nowMs();
|
||||
state.storeFileMtimeMs = fileMtimeMs;
|
||||
|
||||
// Recompute next runs after loading to ensure accuracy
|
||||
recomputeNextRuns(state);
|
||||
if (!opts?.skipRecompute) {
|
||||
recomputeNextRuns(state);
|
||||
}
|
||||
|
||||
if (mutated) {
|
||||
await persist(state);
|
||||
|
||||
Reference in New Issue
Block a user