joni539
joni539

Reputation: 183

Node.js : Know when all http requests are finished

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

Answers (1)

jfriend00
jfriend00

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

Related Questions