docs(FN-3538): clarify pause-safe stuck timeout behavior
- Update enginePaused setting docs to specify stuck-task timers are suspended while pauses are active - Document that paused wall-clock time does not count toward taskStuckTimeoutMs, including shared globalPause windows - Clarify that unpausing restores scheduling and grants active sessions a fresh stuck-task grace window before detection resumes Fusion-Task-Id: FN-3538
This commit is contained in:
@@ -604,6 +604,75 @@ describe("StuckTaskDetector", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("pause lifecycle", () => {
|
||||
it("skips stuck evaluation while paused", async () => {
|
||||
const getSettings = vi.fn().mockResolvedValue({ taskStuckTimeoutMs: 60000 });
|
||||
store = createMockStore({ getSettings });
|
||||
const onStuck = vi.fn();
|
||||
const customDetector = new StuckTaskDetector(store, { onStuck });
|
||||
const session = createMockSession();
|
||||
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true });
|
||||
customDetector.trackTask("FN-001", session);
|
||||
customDetector.pause();
|
||||
vi.advanceTimersByTime(61_000);
|
||||
|
||||
await customDetector.checkNow();
|
||||
|
||||
expect(getSettings).not.toHaveBeenCalled();
|
||||
expect(onStuck).not.toHaveBeenCalled();
|
||||
expect(session.dispose).not.toHaveBeenCalled();
|
||||
expect(customDetector.trackedCount).toBe(1);
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("resets tracked timing on resume so paused interval is not immediately stuck", async () => {
|
||||
store = createMockStore({
|
||||
getSettings: vi.fn().mockResolvedValue({ taskStuckTimeoutMs: 60000 }),
|
||||
});
|
||||
const onStuck = vi.fn();
|
||||
const customDetector = new StuckTaskDetector(store, { onStuck });
|
||||
const session = createMockSession();
|
||||
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true });
|
||||
customDetector.trackTask("FN-001", session);
|
||||
customDetector.pause();
|
||||
vi.advanceTimersByTime(120_000);
|
||||
customDetector.resume();
|
||||
|
||||
await customDetector.checkNow();
|
||||
expect(onStuck).not.toHaveBeenCalled();
|
||||
|
||||
vi.advanceTimersByTime(61_000);
|
||||
await customDetector.checkNow();
|
||||
expect(onStuck).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ taskId: "FN-001", reason: "inactivity" }),
|
||||
);
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("does not refresh tracked timing when resume is called while already unpaused", async () => {
|
||||
store = createMockStore({
|
||||
getSettings: vi.fn().mockResolvedValue({ taskStuckTimeoutMs: 60000 }),
|
||||
});
|
||||
const onStuck = vi.fn();
|
||||
const customDetector = new StuckTaskDetector(store, { onStuck });
|
||||
const session = createMockSession();
|
||||
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true });
|
||||
customDetector.trackTask("FN-001", session);
|
||||
vi.advanceTimersByTime(61_000);
|
||||
|
||||
customDetector.resume();
|
||||
await customDetector.checkNow();
|
||||
|
||||
expect(onStuck).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ taskId: "FN-001", reason: "inactivity" }),
|
||||
);
|
||||
vi.useRealTimers();
|
||||
});
|
||||
});
|
||||
|
||||
describe("checkNow", () => {
|
||||
it("checks stuck tasks immediately and disposes session", async () => {
|
||||
store = createMockStore({
|
||||
|
||||
Reference in New Issue
Block a user