mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 09:51:22 +00:00
Cron: respect aborts in main wake-now retries (#23967)
* Cron: respect aborts in main wake-now retries * Changelog: add main-session cron abort retry fix note * Cron tests: format post-rebase conflict resolution
This commit is contained in:
@@ -607,8 +607,34 @@ export async function executeJobCore(
|
||||
job: CronJob,
|
||||
abortSignal?: AbortSignal,
|
||||
): Promise<CronRunOutcome & CronRunTelemetry & { delivered?: boolean }> {
|
||||
const resolveAbortError = () => ({
|
||||
status: "error" as const,
|
||||
error: timeoutErrorMessage(),
|
||||
});
|
||||
const waitWithAbort = async (ms: number) => {
|
||||
if (!abortSignal) {
|
||||
await new Promise<void>((resolve) => setTimeout(resolve, ms));
|
||||
return;
|
||||
}
|
||||
if (abortSignal.aborted) {
|
||||
return;
|
||||
}
|
||||
await new Promise<void>((resolve) => {
|
||||
const timer = setTimeout(() => {
|
||||
abortSignal.removeEventListener("abort", onAbort);
|
||||
resolve();
|
||||
}, ms);
|
||||
const onAbort = () => {
|
||||
clearTimeout(timer);
|
||||
abortSignal.removeEventListener("abort", onAbort);
|
||||
resolve();
|
||||
};
|
||||
abortSignal.addEventListener("abort", onAbort, { once: true });
|
||||
});
|
||||
};
|
||||
|
||||
if (abortSignal?.aborted) {
|
||||
return { status: "error", error: timeoutErrorMessage() };
|
||||
return resolveAbortError();
|
||||
}
|
||||
if (job.sessionTarget === "main") {
|
||||
const text = resolveJobPayloadTextForMain(job);
|
||||
@@ -629,7 +655,6 @@ export async function executeJobCore(
|
||||
});
|
||||
if (job.wakeMode === "now" && state.deps.runHeartbeatOnce) {
|
||||
const reason = `cron:${job.id}`;
|
||||
const delay = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
|
||||
const maxWaitMs = state.deps.wakeNowHeartbeatBusyMaxWaitMs ?? 2 * 60_000;
|
||||
const retryDelayMs = state.deps.wakeNowHeartbeatBusyRetryDelayMs ?? 250;
|
||||
const waitStartedAt = state.deps.nowMs();
|
||||
@@ -637,7 +662,7 @@ export async function executeJobCore(
|
||||
let heartbeatResult: HeartbeatRunResult;
|
||||
for (;;) {
|
||||
if (abortSignal?.aborted) {
|
||||
return { status: "error", error: timeoutErrorMessage() };
|
||||
return resolveAbortError();
|
||||
}
|
||||
heartbeatResult = await state.deps.runHeartbeatOnce({
|
||||
reason,
|
||||
@@ -650,7 +675,13 @@ export async function executeJobCore(
|
||||
) {
|
||||
break;
|
||||
}
|
||||
if (abortSignal?.aborted) {
|
||||
return resolveAbortError();
|
||||
}
|
||||
if (state.deps.nowMs() - waitStartedAt > maxWaitMs) {
|
||||
if (abortSignal?.aborted) {
|
||||
return resolveAbortError();
|
||||
}
|
||||
state.deps.requestHeartbeatNow({
|
||||
reason,
|
||||
agentId: job.agentId,
|
||||
@@ -658,7 +689,7 @@ export async function executeJobCore(
|
||||
});
|
||||
return { status: "ok", summary: text };
|
||||
}
|
||||
await delay(retryDelayMs);
|
||||
await waitWithAbort(retryDelayMs);
|
||||
}
|
||||
|
||||
if (heartbeatResult.status === "ran") {
|
||||
@@ -669,6 +700,9 @@ export async function executeJobCore(
|
||||
return { status: "error", error: heartbeatResult.reason, summary: text };
|
||||
}
|
||||
} else {
|
||||
if (abortSignal?.aborted) {
|
||||
return resolveAbortError();
|
||||
}
|
||||
state.deps.requestHeartbeatNow({
|
||||
reason: `cron:${job.id}`,
|
||||
agentId: job.agentId,
|
||||
@@ -682,7 +716,7 @@ export async function executeJobCore(
|
||||
return { status: "skipped", error: "isolated job requires payload.kind=agentTurn" };
|
||||
}
|
||||
if (abortSignal?.aborted) {
|
||||
return { status: "error", error: timeoutErrorMessage() };
|
||||
return resolveAbortError();
|
||||
}
|
||||
|
||||
const res = await state.deps.runIsolatedAgentJob({
|
||||
|
||||
Reference in New Issue
Block a user