4 min read
•Question 42 of 62mediumHow to implement graceful shutdown in Node.js?
Properly closing connections on shutdown.
What You'll Learn
- Why graceful shutdown matters
- Handling signals
- Cleanup tasks
Basic Implementation
code.jsJavaScript
const http = require('http');
const server = http.createServer(app);
let connections = new Set();
server.on('connection', (conn) => {
connections.add(conn);
conn.on('close', () => connections.delete(conn));
});
function shutdown(signal) {
console.log(`${signal} received. Shutting down gracefully...`);
// Stop accepting new connections
server.close(() => {
console.log('HTTP server closed');
// Close database connections
mongoose.connection.close(false, () => {
console.log('MongoDB connection closed');
process.exit(0);
});
});
// Force close after timeout
setTimeout(() => {
console.error('Forcing shutdown...');
process.exit(1);
}, 10000);
// Close existing connections
connections.forEach(conn => conn.end());
setTimeout(() => {
connections.forEach(conn => conn.destroy());
}, 5000);
}
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));Express with Cleanup
code.jsJavaScript
const express = require('express');
const app = express();
// Health check endpoint
let isShuttingDown = false;
app.use((req, res, next) => {
if (isShuttingDown) {
res.set('Connection', 'close');
return res.status(503).send('Server is shutting down');
}
next();
});
function gracefulShutdown() {
isShuttingDown = true;
server.close(async () => {
await db.disconnect();
await redis.quit();
await messageQueue.close();
process.exit(0);
});
}