Fix shutdown with active WebSocket clients

This commit is contained in:
2026-06-24 15:44:15 +08:00
parent ad3cccb2eb
commit 6f2f2c7c09
+44 -4
View File
@@ -11,6 +11,7 @@ const PORT = Number.parseInt(process.env.PORT || '3000', 10);
const HOST = process.env.HOST || '127.0.0.1';
const TAIL_LINES = Number.parseInt(process.env.TAIL_LINES || '200', 10);
const WATCH_INTERVAL_MS = Number.parseInt(process.env.WATCH_INTERVAL_MS || '500', 10);
const SHUTDOWN_TIMEOUT_MS = Number.parseInt(process.env.SHUTDOWN_TIMEOUT_MS || '3000', 10);
const PUBLIC_DIR = path.join(__dirname, 'public');
const LOG_FILE = path.resolve(process.env.LOG_FILE || process.argv[2] || 'sample.log');
@@ -275,14 +276,53 @@ async function main() {
console.log(`Streaming ${LOG_FILE}`);
});
function shutdown() {
let shuttingDown = false;
function shutdown(signal) {
if (shuttingDown) {
console.error(`${signal} received again; forcing shutdown.`);
process.exit(1);
}
shuttingDown = true;
console.log(`${signal} received; shutting down.`);
fs.unwatchFile(LOG_FILE);
const shutdownTimer = setTimeout(() => {
console.error(`Shutdown exceeded ${SHUTDOWN_TIMEOUT_MS}ms; forcing exit.`);
process.exit(1);
}, SHUTDOWN_TIMEOUT_MS);
shutdownTimer.unref();
const terminateTimer = setTimeout(() => {
for (const client of wss.clients) {
if (client.readyState !== WebSocket.CLOSED) {
client.terminate();
}
}
}, Math.min(500, SHUTDOWN_TIMEOUT_MS));
terminateTimer.unref();
for (const client of wss.clients) {
client.close(1001, 'Server shutting down');
}
wss.close();
server.close(() => process.exit(0));
server.close((error) => {
clearTimeout(shutdownTimer);
if (error) {
console.error(error);
process.exit(1);
}
process.exit(0);
});
}
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
process.on('SIGINT', () => shutdown('SIGINT'));
process.on('SIGTERM', () => shutdown('SIGTERM'));
}
main().catch((error) => {