Olly Smith

Graceful server shutdown with node.js / express

howmanyleft.co.uk runs its node.js workers behind supervisord. To avoid dropping requests with 502s when restarting workers, I hook into the SIGTERM signal and call close() on the HTTP server. This stops the server from listening for new connections, and once all the open connections are complete, the worker exits.

Here’s a quick example:

var http = require('http');

var app = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  setTimeout(function () { res.end('OK\n'); }, 5000);
});

process.on('SIGTERM', function () {
  console.log("Closing");
  app.close();
});

app.listen(3000);

Since I’m using redis on howmanyleft, I need to close my redis connection gracefully too. The close event on the HTTP server fires when all connections have closed, so close my redis connection there. node_redis flushes all active redis commands when you call quit, so I won’t lose any data.

var http = require('http'),
    redis = require('redis').createClient();

var app = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  setTimeout(function () { res.end('OK\n'); }, 5000);
});

process.on('SIGTERM', function () {
  console.log("Closing");
  app.close();
});

app.on('close', function () {
  console.log("Closed");
  redis.quit();
});

app.listen(3000);