LearnBoost / cluster

Node.JS multi-core server manager with plugins support.
http://learnboost.github.com/cluster
MIT License
2.29k stars 159 forks source link

Custom cleanup in workers before graceful shutdown. #167

Open ctavan opened 12 years ago

ctavan commented 12 years ago

The criterion for graceful shutdown of a worker is that there are no more open server-connections: https://github.com/LearnBoost/cluster/blob/master/lib/worker.js#L162-181

I've got a use case where I perform deferred database operations even after the tcp-connection has been closed. This could potentially lead to problems when a worker is killed on graceful shutdown before these db operations have finished.

Since I don't want just the http-server to shutdown gracefully but also the db operations, I thus need some way to perform cleanup within the worker instance during a graceful worker shutdown.

I've come up with a solution that kinda works, but I'm not really happy with it:

When a worker instance is gracefully closed in Worker.close() a 'worker closing' event is emitted. This event can be listened on on the current worker's master instance where a reference to the actual workers this.server object is present. Increasing server.connections by one gives some time (until timeout) to perform cleanup tasks like gracefully finishing deferred db operations before the worker gets killed.

Here's how you would use it:

var cluster = require('cluster');

var proc = cluster('app.js').listen(3000);

if (proc.isWorker) {
  proc.on('worker closing', function() {
    console.log('closing worker now');

    var server = this.server;

    // Increase connection count, so cluster waits before shutting
    // down this worker
    server.connections++;

    // Perform cleanup
    cleanupStuff(function() {
      server.connections--;
    });
  });
}

I'm thankful for any feedback and hints on that.

Cheers, Christoph