Skip to content

Commit 150e74a

Browse files
authored
fix: improve telemetry worker stderr cleanup (#3648)
* fix: improve telemetry worker stderr cleanup to prevent hanging Replace setImmediate + destroy() with process.stderr.end() callback to ensure all buffered writes are flushed before exiting. Add fallback exit in finally block to prevent worker from hanging if end() fails. This properly releases the inherited stderr file descriptor in debug mode, preventing the parent process from being blocked. * fix: only close stderr in telemetry worker when DEBUG is active Only call process.stderr.end() when DEBUG env var is set, mirroring the parent process logic where stderr is inherited only in DEBUG mode. When stderr is ignored, closing it is unnecessary and could cause issues.
1 parent ede6655 commit 150e74a

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

src/lib/analytics-telemetry/telemetry-worker.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,27 @@ const MAX_WORKER_LIFETIME_MS = 10000
1313

1414
/**
1515
* Close stderr before exiting to avoid keeping parent process alive
16-
* This is important when stderr is inherited in DEBUG mode
16+
* This is only necessary when stderr is inherited in DEBUG mode
1717
*/
1818
function exitWorker(code: number): void {
19-
// Use setImmediate to allow any pending stderr writes to flush
20-
// before destroying the stream
21-
setImmediate(() => {
19+
// Close stderr if it was inherited (DEBUG mode)
20+
if (process.env.DEBUG) {
2221
try {
23-
// Close stderr to release the file descriptor reference to parent
24-
process.stderr.destroy()
25-
} catch {
26-
// Ignore errors during cleanup
22+
// End stderr gracefully, flushing all pending writes
23+
// This properly releases the file descriptor reference to parent
24+
process.stderr.end(() => {
25+
process.exit(code)
26+
})
27+
} finally {
28+
// Fallback: ensure we exit even if end() fails or callback never fires
29+
// Use setImmediate to give the end() callback a chance to run first
30+
setImmediate(() => {
31+
process.exit(code)
32+
})
2733
}
28-
34+
} else {
2935
process.exit(code)
30-
})
36+
}
3137
}
3238

3339
setTimeout(() => {

0 commit comments

Comments
 (0)