diff --git a/libs/portal/stalker/data-access/src/lib/background-interval.spec.ts b/libs/portal/stalker/data-access/src/lib/background-interval.spec.ts index da95a2d05..dc05d6505 100644 --- a/libs/portal/stalker/data-access/src/lib/background-interval.spec.ts +++ b/libs/portal/stalker/data-access/src/lib/background-interval.spec.ts @@ -98,4 +98,19 @@ describe('createBackgroundInterval', () => { jest.advanceTimersByTime(60_000); expect(callback).toHaveBeenCalledTimes(1); }); + + it('stays stopped when a worker error arrives after stop', () => { + scope.Worker = FakeWorker; + const callback = jest.fn(); + + const stop = createBackgroundInterval(callback, 30_000); + const [worker] = FakeWorker.instances; + const lateError = worker.onerror; + stop(); + lateError?.(new Event('error')); + + jest.advanceTimersByTime(90_000); + expect(callback).not.toHaveBeenCalled(); + expect(jest.getTimerCount()).toBe(0); + }); }); diff --git a/libs/portal/stalker/data-access/src/lib/background-interval.ts b/libs/portal/stalker/data-access/src/lib/background-interval.ts index f10f30225..c51950eec 100644 --- a/libs/portal/stalker/data-access/src/lib/background-interval.ts +++ b/libs/portal/stalker/data-access/src/lib/background-interval.ts @@ -24,7 +24,10 @@ export function createBackgroundInterval( periodMs: number ): () => void { let fallback: ReturnType | undefined; + let stopped = false; const startFallback = () => { + // A worker error that arrives after stop() must not revive the tick. + if (stopped) return; fallback ??= setInterval(callback, periodMs); }; const ticker = startTickerWorker(); @@ -45,6 +48,11 @@ export function createBackgroundInterval( startFallback(); } return () => { + stopped = true; + if (ticker) { + ticker.worker.onmessage = null; + ticker.worker.onerror = null; + } stopWorker(); if (fallback !== undefined) clearInterval(fallback); };