Implement Graceful Shutdown
A production Node.js application should shut down cleanly when it receives termination signals.
A graceful shutdown should:
- Stop accepting new connections.
- Notify or disconnect active clients according to application requirements.
- Close the Socket.IO server.
- Close the HTTP server.
- Close Redis connections.
- Exit the process after cleanup.
This is especially important in Docker and Kubernetes deployments where applications receive termination signals during restarts and deployments.
The exact shutdown behavior should be designed according to your deployment platform and connection-draining requirements.
Production deployments should enforce a shutdown deadline. If cleanup exceeds the orchestrator termination grace period, the process may be forcibly terminated.
async function shutdown(signal) {
console.log(`${signal} received. Shutting down...`);
io.disconnectSockets(true);
await new Promise((resolve, reject) => {
httpServer.close((error) => {
if (error) reject(error);
else resolve();
});
});
await Promise.all([
pubClient.quit(),
subClient.quit()
]);
process.exit(0);
}
process.on('SIGTERM', () => {
shutdown('SIGTERM').catch(console.error);
});
process.on('SIGINT', () => {
shutdown('SIGINT').catch(console.error);
});Disconnects active sockets, closes the HTTP server, and then closes Redis connections. This example assumes the io, httpServer, pubClient, and subClient variables are available in the application module.
Handle SIGTERM and SIGINT.
Close active resources before exiting.
Design shutdown around the deployment platform's termination deadline.