mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix: stagger missed cron jobs on restart (#18925) (thanks @rexlunae)
This commit is contained in:
@@ -70,6 +70,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Gateway/config restart guard: validate config before service start/restart and keep post-SIGUSR1 startup failures from crashing the gateway process, reducing invalid-config restart loops and macOS permission loss. Landed from contributor PR #38699 by @lml2468. Thanks @lml2468.
|
||||
- Gateway/launchd respawn detection: treat `XPC_SERVICE_NAME` as a launchd supervision hint so macOS restarts exit cleanly under launchd instead of attempting detached self-respawn. Landed from contributor PR #20555 by @dimat. Thanks @dimat.
|
||||
- Telegram/poll restart cleanup: abort the in-flight Telegram API fetch when shutdown or forced polling restarts stop a runner, preventing stale `getUpdates` long polls from colliding with the replacement runner. Landed from contributor PR #23950 by @Gkinthecodeland. Thanks @Gkinthecodeland.
|
||||
- Cron/restart catch-up staggering: limit immediate missed-job replay on startup and reschedule the deferred remainder from the post-catchup clock so restart bursts do not starve the gateway or silently skip overdue recurring jobs. Landed from contributor PR #18925 by @rexlunae. Thanks @rexlunae.
|
||||
- Cron/owner-only tools: pass trusted isolated cron runs into the embedded agent with owner context so `cron`/`gateway` tooling remains available after the owner-auth hardening narrowed direct-message ownership inference.
|
||||
|
||||
## 2026.3.7
|
||||
|
||||
@@ -2,9 +2,9 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { CronService } from "./service.js";
|
||||
import { createCronServiceState } from "./state.js";
|
||||
import { setupCronServiceSuite } from "./service.test-harness.js";
|
||||
import { runMissedJobs } from "./timer.js";
|
||||
import { createCronServiceState } from "./service/state.js";
|
||||
import { runMissedJobs } from "./service/timer.js";
|
||||
|
||||
const { logger: noopLogger, makeStorePath } = setupCronServiceSuite({
|
||||
prefix: "openclaw-cron-",
|
||||
@@ -406,8 +406,9 @@ describe("CronService restart catch-up", () => {
|
||||
expect(staggeredJobs[1]?.state.nextRunAtMs).toBeGreaterThan(
|
||||
staggeredJobs[0]?.state.nextRunAtMs ?? 0,
|
||||
);
|
||||
expect((staggeredJobs[1]?.state.nextRunAtMs ?? 0) - (staggeredJobs[0]?.state.nextRunAtMs ?? 0))
|
||||
.toBe(5_000);
|
||||
expect(
|
||||
(staggeredJobs[1]?.state.nextRunAtMs ?? 0) - (staggeredJobs[0]?.state.nextRunAtMs ?? 0),
|
||||
).toBe(5_000);
|
||||
|
||||
await store.cleanup();
|
||||
});
|
||||
|
||||
@@ -858,7 +858,9 @@ export async function runMissedJobs(
|
||||
startupCandidates: [] as Array<{ jobId: string; job: CronJob }>,
|
||||
};
|
||||
}
|
||||
const sorted = missed.toSorted((a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0));
|
||||
const sorted = missed.toSorted(
|
||||
(a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0),
|
||||
);
|
||||
const startupCandidates = sorted.slice(0, maxImmediate);
|
||||
const deferred = sorted.slice(maxImmediate);
|
||||
if (deferred.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user