Reputation: 183
Hello I'm running my app with Node.js cluster module and I'm trying to find a way of gracefully exiting a worker without loosing any request.
So I use server.close() to stop accepting new requests but how to know if the actual requests being processed have finished ?
I came up with this hack which works fine :
var http = require('http');
var server = http.createServer(function(res, req) {
setTimeout(function() { // simulate a request which takes time (1sec) to finish
req.end('hallo');
}, 1000);
}).listen(8080);
server._requests = 0;
server.on('request', function(req, res) {
server._requests += 1;
res.once('finish', function() {
server._requests -= 1;
if (server._requests === 0)
server.emit('no_more_requests');
});
});
function gracefulExit() {
server.close();
if (server._requests === 0) process.exit(0); // exit right away
server.once('no_more_requests', process.exit); // or wait
}
process.on('SIGTERM', gracefulExit);
process.on('SIGINT', gracefulExit);
But is there a more elegant way of doing it ?
Upvotes: 4
Views: 1226
Reputation: 707258
You don't have to close your server manually. Instead, you can unref()
the server. This tells node that as soon as this server object is not being used any more and no other like resources are in use, then the process can exit.
See the nodejs server.unref()
doc for more details.
Note, you can't do this immediately because then your server will startup and the process will exit before any requests are handled. Instead, you will need to decide sometime in the future after your server has been running that you then want to server.unref()
it and let it shut down.
Note, the same feature exists for timers in node.js so you can decide if a timer should keep your processing running or not.
Upvotes: 2