supervisor配下でcluster.jsを動かすためのTips

現在nodeアプリケーションをsupervisordでデーモン管理しているのですが、
こいつをcluster.jsでマルチコア対応したところ
デーモン管理から外れてしまうという現象が発生しました。

発生する小さなスクリプト
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  app = require('./app');
}


このスクリプトで supervisorctl stop すると
子プロセスが落ちないでデーモンとして残ってしまう。


Google先生に聞いてみたところ
マスタープロセスからシグナル検知して
子プロセスを行儀よくkillしてあげれば大丈夫っぽいです。


※2012/10/19 子プロセス内で落ちた時にも対応できるように修正
※2012/11/25 node0.8用の記述追加

直したスクリプト
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;

var childProcesses = [];

if (cluster.isMaster) {

    for (var i = 0, childProcesses = []; i < numCPUs; i++) {
        childProcesses[i] = cluster.fork();
    }

    var signals = ['SIGINT', 'SIGTERM', 'SIGQUIT'];
    for (s in signals) {
        process.on(signals[s], function() {
            for (var j in childProcesses)
                childProcesses[j].kill();
                // for v0.8
                //childProcesses[j].process.kill();
            process.exit(1);
        });
    }

    cluster.on('death', function(worker) {
        console.log('worker %s died. restart...', worker.pid);
        // add child process
        var child = cluster.fork();
        childProcesses.push(child);
    });
} else {
  app = require('./app');
}


これで問題なくいけたようだ。*1