mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 09:47:40 +00:00
fix: cron wakeMode now waits for heartbeat (#666) (thanks @roshanasingh4)
This commit is contained in:
@@ -4,6 +4,7 @@ import path from "node:path";
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { HeartbeatRunResult } from "../infra/heartbeat-wake.js";
|
||||
import { CronService } from "./service.js";
|
||||
|
||||
const noopLogger = {
|
||||
@@ -78,6 +79,68 @@ describe("CronService", () => {
|
||||
await store.cleanup();
|
||||
});
|
||||
|
||||
it("wakeMode now waits for heartbeat completion when available", async () => {
|
||||
const store = await makeStorePath();
|
||||
const enqueueSystemEvent = vi.fn();
|
||||
const requestHeartbeatNow = vi.fn();
|
||||
|
||||
let now = 0;
|
||||
const nowMs = () => {
|
||||
now += 10;
|
||||
return now;
|
||||
};
|
||||
|
||||
let resolveHeartbeat: ((res: HeartbeatRunResult) => void) | null = null;
|
||||
const runHeartbeatOnce = vi.fn(
|
||||
async () =>
|
||||
await new Promise<HeartbeatRunResult>((resolve) => {
|
||||
resolveHeartbeat = resolve;
|
||||
}),
|
||||
);
|
||||
|
||||
const cron = new CronService({
|
||||
storePath: store.storePath,
|
||||
cronEnabled: true,
|
||||
log: noopLogger,
|
||||
nowMs,
|
||||
enqueueSystemEvent,
|
||||
requestHeartbeatNow,
|
||||
runHeartbeatOnce,
|
||||
runIsolatedAgentJob: vi.fn(async () => ({ status: "ok" })),
|
||||
});
|
||||
|
||||
await cron.start();
|
||||
const job = await cron.add({
|
||||
name: "wakeMode now waits",
|
||||
enabled: true,
|
||||
schedule: { kind: "at", atMs: 1 },
|
||||
sessionTarget: "main",
|
||||
wakeMode: "now",
|
||||
payload: { kind: "systemEvent", text: "hello" },
|
||||
});
|
||||
|
||||
const runPromise = cron.run(job.id, "force");
|
||||
for (let i = 0; i < 10; i++) {
|
||||
if (runHeartbeatOnce.mock.calls.length > 0) break;
|
||||
// Let the locked() chain progress.
|
||||
await Promise.resolve();
|
||||
}
|
||||
|
||||
expect(runHeartbeatOnce).toHaveBeenCalledTimes(1);
|
||||
expect(requestHeartbeatNow).not.toHaveBeenCalled();
|
||||
expect(enqueueSystemEvent).toHaveBeenCalledWith("hello");
|
||||
expect(job.state.runningAtMs).toBeTypeOf("number");
|
||||
|
||||
resolveHeartbeat?.({ status: "ran", durationMs: 123 });
|
||||
await runPromise;
|
||||
|
||||
expect(job.state.lastStatus).toBe("ok");
|
||||
expect(job.state.lastDurationMs).toBeGreaterThan(0);
|
||||
|
||||
cron.stop();
|
||||
await store.cleanup();
|
||||
});
|
||||
|
||||
it("runs an isolated job and posts summary to main", async () => {
|
||||
const store = await makeStorePath();
|
||||
const enqueueSystemEvent = vi.fn();
|
||||
|
||||
Reference in New Issue
Block a user