From e5f8d79c3bddd0291d3600463224d36a0a19a422 Mon Sep 17 00:00:00 2001 From: bluwy Date: Tue, 14 Jan 2025 15:24:22 +0800 Subject: [PATCH] fix: use shared sigterm callback --- packages/vite/src/node/utils.ts | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 65316c1f6fa8de..582a3c2c6e43ef 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -1535,20 +1535,34 @@ export function partialEncodeURIPath(uri: string): string { return filePath.replaceAll('%', '%25') + postfix } +type SigtermCallback = (signal?: 'SIGTERM', exitCode?: number) => Promise + +// Use a shared callback when attaching sigterm listeners to avoid `MaxListenersExceededWarning` +const sigtermCallbacks = new Set() +const parentSigtermCallback: SigtermCallback = async (signal, exitCode) => { + await Promise.all([...sigtermCallbacks].map((cb) => cb(signal, exitCode))) +} + export const setupSIGTERMListener = ( callback: (signal?: 'SIGTERM', exitCode?: number) => Promise, ): void => { - process.once('SIGTERM', callback) - if (process.env.CI !== 'true') { - process.stdin.on('end', callback) + if (sigtermCallbacks.size === 0) { + process.once('SIGTERM', parentSigtermCallback) + if (process.env.CI !== 'true') { + process.stdin.on('end', parentSigtermCallback) + } } + sigtermCallbacks.add(callback) } export const teardownSIGTERMListener = ( callback: Parameters[0], ): void => { - process.off('SIGTERM', callback) - if (process.env.CI !== 'true') { - process.stdin.off('end', callback) + sigtermCallbacks.delete(callback) + if (sigtermCallbacks.size === 0) { + process.off('SIGTERM', parentSigtermCallback) + if (process.env.CI !== 'true') { + process.stdin.off('end', parentSigtermCallback) + } } }