From d6ea20bfdab9e75658dbfe9eb9f0e8f7c5f19a70 Mon Sep 17 00:00:00 2001 From: NOXX - Commiter Date: Wed, 17 Jun 2026 23:26:10 +0300 Subject: [PATCH] fix(timers): unref background interval timers so they don't block clean shutdown (#4117) Integrated into release/v3.8.28 (r8) --- open-sse/services/autoRefreshDaemon.ts | 2 ++ src/lib/services/healthCheck.ts | 2 ++ src/server/ws/liveServer.ts | 2 ++ 3 files changed, 6 insertions(+) diff --git a/open-sse/services/autoRefreshDaemon.ts b/open-sse/services/autoRefreshDaemon.ts index 29c22a4a14..a08471f655 100644 --- a/open-sse/services/autoRefreshDaemon.ts +++ b/open-sse/services/autoRefreshDaemon.ts @@ -79,6 +79,8 @@ class AutoRefreshDaemon { this.timerId = setInterval(() => { this.check().catch(() => {}); }, this.checkIntervalMs); + // Don't keep the process alive solely for this periodic daemon. + (this.timerId as { unref?: () => void })?.unref?.(); console.log( `[AutoRefreshDaemon] Started — checking ${this.credentialStore.size} credentials every ${this.checkIntervalMs / 1000}s` diff --git a/src/lib/services/healthCheck.ts b/src/lib/services/healthCheck.ts index 98c6b83262..0a394df95d 100644 --- a/src/lib/services/healthCheck.ts +++ b/src/lib/services/healthCheck.ts @@ -25,6 +25,8 @@ export class HealthChecker { this.consecutiveFailures = 0; this.currentHealth = "unknown"; this.timer = setInterval(() => void this.poll(), this.intervalMs); + // Don't keep the process alive solely for the health poller. + (this.timer as { unref?: () => void })?.unref?.(); } stop(): void { diff --git a/src/server/ws/liveServer.ts b/src/server/ws/liveServer.ts index 9ff5ef6ba7..ccc1f7e8e9 100644 --- a/src/server/ws/liveServer.ts +++ b/src/server/ws/liveServer.ts @@ -440,6 +440,8 @@ function startHeartbeat(server: WebSocketServer): void { sendTo(client.ws, { type: "pong" } as WsServerMessage); } }, HEARTBEAT_INTERVAL_MS); + // Don't keep the process alive solely for the heartbeat (it is also cleared on close). + (interval as { unref?: () => void })?.unref?.(); server.on("close", () => clearInterval(interval)); }