diff --git a/src/hooks/comment-checker/hook.ts b/src/hooks/comment-checker/hook.ts index 06ecc8bbf..56632b1f9 100644 --- a/src/hooks/comment-checker/hook.ts +++ b/src/hooks/comment-checker/hook.ts @@ -22,7 +22,12 @@ import { processWithCli, processApplyPatchEditsWithCli, } from "./cli-runner" -import { registerPendingCall, startPendingCallCleanup, takePendingCall } from "./pending-calls" +import { + registerPendingCall, + startPendingCallCleanup, + stopPendingCallCleanup, + takePendingCall, +} from "./pending-calls" import * as fs from "fs" import { tmpdir } from "os" @@ -180,5 +185,8 @@ export function createCommentCheckerHooks(config?: CommentCheckerConfig) { debugLog("tool.execute.after failed:", err) } }, + dispose: (): void => { + stopPendingCallCleanup() + }, } } diff --git a/src/hooks/comment-checker/pending-calls.test.ts b/src/hooks/comment-checker/pending-calls.test.ts index 972c16634..31f01d2fe 100644 --- a/src/hooks/comment-checker/pending-calls.test.ts +++ b/src/hooks/comment-checker/pending-calls.test.ts @@ -35,4 +35,43 @@ describe("pending-calls cleanup interval", () => { globalThis.setInterval = originalSetInterval } }) + + test("#given cleanup timer already started #when stop cleanup runs #then interval state resets for future reuse", async () => { + //#given + const originalSetInterval = globalThis.setInterval + const originalClearInterval = globalThis.clearInterval + let intervalHandle: ReturnType | undefined + let clearCalls = 0 + + globalThis.setInterval = (( + _handler: TimerHandler, + _timeout?: number, + ..._args: any[] + ) => { + intervalHandle = { unref: () => {} } as unknown as ReturnType + return intervalHandle + }) as unknown as typeof setInterval + + globalThis.clearInterval = ((handle?: ReturnType) => { + if (handle === intervalHandle) { + clearCalls += 1 + } + }) as unknown as typeof clearInterval + + try { + const modulePath = new URL("./pending-calls.ts", import.meta.url).pathname + const pendingCallsModule = await import(`${modulePath}?pending-calls-test-stop`) + pendingCallsModule.startPendingCallCleanup() + + //#when + pendingCallsModule.stopPendingCallCleanup() + pendingCallsModule.startPendingCallCleanup() + + //#then + expect(clearCalls).toBe(1) + } finally { + globalThis.setInterval = originalSetInterval + globalThis.clearInterval = originalClearInterval + } + }) }) diff --git a/src/hooks/comment-checker/pending-calls.ts b/src/hooks/comment-checker/pending-calls.ts index 4144ae952..dd2fcc12d 100644 --- a/src/hooks/comment-checker/pending-calls.ts +++ b/src/hooks/comment-checker/pending-calls.ts @@ -24,6 +24,15 @@ export function startPendingCallCleanup(): void { } } +export function stopPendingCallCleanup(): void { + pendingCalls.clear() + if (cleanupInterval) { + clearInterval(cleanupInterval) + cleanupInterval = undefined + } + cleanupIntervalStarted = false +} + export function registerPendingCall(callID: string, pendingCall: PendingCall): void { pendingCalls.set(callID, pendingCall) }