Merge pull request #65 from bluk1020/fix/stuck-detector-workflow-timeout-fallback
fix: keep stuck detector active by default
This commit is contained in:
@@ -718,21 +718,52 @@ describe("StuckTaskDetector", () => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("does nothing when timeout is disabled", async () => {
|
||||
it("does not couple stuck detection to workflow step timeout", async () => {
|
||||
store = createMockStore({
|
||||
getSettings: vi.fn().mockResolvedValue({ taskStuckTimeoutMs: undefined }),
|
||||
getSettings: vi.fn().mockResolvedValue({
|
||||
taskStuckTimeoutMs: undefined,
|
||||
workflowStepTimeoutMs: 60_000,
|
||||
}),
|
||||
});
|
||||
const customDetector = new StuckTaskDetector(store);
|
||||
const onStuck = vi.fn();
|
||||
const customDetector = new StuckTaskDetector(store, { onStuck });
|
||||
const session = createMockSession();
|
||||
|
||||
customDetector.trackTask("FN-001", session);
|
||||
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true });
|
||||
vi.advanceTimersByTime(61000);
|
||||
vi.advanceTimersByTime(61_000);
|
||||
|
||||
await customDetector.checkNow();
|
||||
|
||||
expect(store.moveTask).not.toHaveBeenCalled();
|
||||
expect(onStuck).not.toHaveBeenCalled();
|
||||
expect(session.dispose).not.toHaveBeenCalled();
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("kills stuck sessions when the project default stuck timeout is present", async () => {
|
||||
store = createMockStore({
|
||||
getSettings: vi.fn().mockResolvedValue({
|
||||
taskStuckTimeoutMs: 600_000,
|
||||
workflowStepTimeoutMs: 60_000,
|
||||
}),
|
||||
});
|
||||
const onStuck = vi.fn();
|
||||
const customDetector = new StuckTaskDetector(store, { onStuck });
|
||||
const session = createMockSession();
|
||||
|
||||
customDetector.trackTask("FN-001", session);
|
||||
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true });
|
||||
vi.advanceTimersByTime(601_000);
|
||||
|
||||
await customDetector.checkNow();
|
||||
|
||||
expect(onStuck).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ taskId: "FN-001", reason: "inactivity" }),
|
||||
);
|
||||
expect(session.dispose).toHaveBeenCalled();
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
* - `recordProgress(taskId)` — step transitions (in-progress, done, skipped); resets counters
|
||||
*
|
||||
* The detector polls at a configurable interval and compares timestamps against
|
||||
* `taskStuckTimeoutMs` from settings.
|
||||
* `taskStuckTimeoutMs` from settings. Project defaults keep this active by
|
||||
* default while keeping workflow-step execution timeouts independent.
|
||||
*/
|
||||
|
||||
import type { TaskStore, Settings } from "@fusion/core";
|
||||
@@ -471,7 +472,7 @@ export class StuckTaskDetector {
|
||||
if (settings.globalPause || settings.enginePaused) return;
|
||||
|
||||
const timeoutMs = settings.taskStuckTimeoutMs;
|
||||
if (!timeoutMs || timeoutMs <= 0) return; // Disabled
|
||||
if (!timeoutMs || timeoutMs <= 0) return; // Disabled when task stuck timeout is explicitly unset/disabled
|
||||
|
||||
const stuckTasks: string[] = [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user