Skip to content

Instantly share code, notes, and snippets.

@rla
Created June 29, 2012 17:54
Show Gist options
  • Save rla/3019602 to your computer and use it in GitHub Desktop.
Save rla/3019602 to your computer and use it in GitHub Desktop.
Node.js 0.8.x cluster helper
var cluster = require('cluster');
var config = require('../config.json');
var fs = require('fs');
// Helper module to use cluster.
var pidfile = config.server.pidfile;
// Signals that can be caught and handled.
var signals = [ 'SIGTERM', 'SIGINT', 'SIGHUP' ];
// Initializes and starts cluster.
// Function runOnMaster is run only on the master process
// and function runOnWorker is run only on the worker processes.
// Function runOnWorkerEnd is run on worker shutdown and must
// accept callback.
exports.init = function(runOnMaster, runOnWorker, runOnWorkerEnd) {
if (cluster.isMaster) {
master(runOnMaster);
} else {
worker(runOnWorker, runOnWorkerEnd);
}
};
function master(runOnMaster) {
console.log('Master starting');
process.title = config.server.masterTitle;
for (var i = 0; i < config.server.processes; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code) {
console.log('Worker exit code ' + code);
if (!worker.suicide && code !== 0) {
console.log('Worker ' + worker.process.pid + ' died');
setTimeout(function() {
cluster.fork();
}, 4000);
}
});
signals.forEach(function(e) {
process.on(e, stopMaster);
});
runOnMaster();
fs.writeFileSync(pidfile, process.pid);
console.log('Master started');
}
function worker(runOnWorker, runOnWorkerEnd) {
console.log('Starting worker ' + process.pid);
process.title = config.server.workerTitle;
runOnWorker();
signals.forEach(function(e) {
process.on(e, function() {
stopWorker(runOnWorkerEnd);
});
});
console.log('Worker ' + process.pid + ' started');
}
function stopMaster() {
console.log('Master stopping.');
Object.keys(cluster.workers).forEach(function(uid) {
cluster.workers[uid].process.kill();
});
fs.unlinkSync(pidfile);
console.log('Master stopped.');
process.exit(0);
}
var workerStopping = false;
function stopWorker(runOnWorkerEnd) {
if (workerStopping) {
return;
}
workerStopping = true;
console.log('Stopping worker ' + process.pid);
runOnWorkerEnd(function() {
console.log('Worker ' + process.pid + ' stopped');
process.exit(0);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment