mirror of https://github.com/openclaw/openclaw.git
fix: harden compaction timeout follow-ups
This commit is contained in:
parent
f77a684131
commit
6a458ef29e
|
|
@ -76,6 +76,20 @@ describe("compactWithSafetyTimeout", () => {
|
|||
expect(onCancel).toHaveBeenCalledTimes(1);
|
||||
expect(vi.getTimerCount()).toBe(0);
|
||||
});
|
||||
|
||||
it("ignores onCancel errors and still rejects with the timeout", async () => {
|
||||
vi.useFakeTimers();
|
||||
const compactPromise = compactWithSafetyTimeout(() => new Promise<never>(() => {}), 30, {
|
||||
onCancel: () => {
|
||||
throw new Error("abortCompaction failed");
|
||||
},
|
||||
});
|
||||
const timeoutAssertion = expect(compactPromise).rejects.toThrow("Compaction timed out");
|
||||
|
||||
await vi.advanceTimersByTimeAsync(30);
|
||||
await timeoutAssertion;
|
||||
expect(vi.getTimerCount()).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveCompactionTimeoutMs", () => {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,12 @@ export async function compactWithSafetyTimeout<T>(
|
|||
return;
|
||||
}
|
||||
canceled = true;
|
||||
try {
|
||||
opts?.onCancel?.();
|
||||
} catch {
|
||||
// Best-effort cancellation hook. Keep the timeout/abort path intact even
|
||||
// if the underlying compaction cancel operation throws.
|
||||
}
|
||||
};
|
||||
|
||||
return await withTimeout(
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ import { flushPendingToolResultsAfterIdle } from "../wait-for-idle-before-flush.
|
|||
import { waitForCompactionRetryWithAggregateTimeout } from "./compaction-retry-aggregate-timeout.js";
|
||||
import {
|
||||
resolveRunTimeoutDuringCompaction,
|
||||
resolveRunTimeoutWithCompactionGraceMs,
|
||||
selectCompactionTimeoutSnapshot,
|
||||
shouldFlagCompactionTimeout,
|
||||
} from "./compaction-timeout.js";
|
||||
|
|
@ -1708,7 +1709,10 @@ export async function runEmbeddedAttempt(
|
|||
const sessionLock = await acquireSessionWriteLock({
|
||||
sessionFile: params.sessionFile,
|
||||
maxHoldMs: resolveSessionLockMaxHoldFromTimeout({
|
||||
timeoutMs: params.timeoutMs,
|
||||
timeoutMs: resolveRunTimeoutWithCompactionGraceMs({
|
||||
runTimeoutMs: params.timeoutMs,
|
||||
compactionTimeoutMs: resolveCompactionTimeoutMs(params.config),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
|||
import { castAgentMessage } from "../../test-helpers/agent-message-fixtures.js";
|
||||
import {
|
||||
resolveRunTimeoutDuringCompaction,
|
||||
resolveRunTimeoutWithCompactionGraceMs,
|
||||
selectCompactionTimeoutSnapshot,
|
||||
shouldFlagCompactionTimeout,
|
||||
} from "./compaction-timeout.js";
|
||||
|
|
@ -62,6 +63,15 @@ describe("compaction-timeout helpers", () => {
|
|||
).toBe("abort");
|
||||
});
|
||||
|
||||
it("adds one compaction grace window to the run timeout budget", () => {
|
||||
expect(
|
||||
resolveRunTimeoutWithCompactionGraceMs({
|
||||
runTimeoutMs: 600_000,
|
||||
compactionTimeoutMs: 900_000,
|
||||
}),
|
||||
).toBe(1_500_000);
|
||||
});
|
||||
|
||||
it("uses pre-compaction snapshot when compaction timeout occurs", () => {
|
||||
const pre = [castAgentMessage({ role: "assistant", content: "pre" })] as const;
|
||||
const current = [castAgentMessage({ role: "assistant", content: "current" })] as const;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@ export function resolveRunTimeoutDuringCompaction(params: {
|
|||
return params.graceAlreadyUsed ? "abort" : "extend";
|
||||
}
|
||||
|
||||
export function resolveRunTimeoutWithCompactionGraceMs(params: {
|
||||
runTimeoutMs: number;
|
||||
compactionTimeoutMs: number;
|
||||
}): number {
|
||||
return params.runTimeoutMs + params.compactionTimeoutMs;
|
||||
}
|
||||
|
||||
export type SnapshotSelectionParams = {
|
||||
timedOutDuringCompaction: boolean;
|
||||
preCompactionSnapshot: AgentMessage[] | null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue