Created
April 3, 2013 07:26
-
-
Save sansmischevia/5299114 to your computer and use it in GitHub Desktop.
basic cluster bootloader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var cluster = require('cluster'), | |
os = require('os'), | |
http = require('http'); | |
// List of 'active' workers: | |
var workers = []; | |
var start_count = 0; | |
// The amount of time we wait before killing a process during a reload: | |
var DEATH_TIMEOUT = 60000; // 1 minute | |
var RESTART_TIMEOUT = 50400000; // 14 hours | |
// Initialize the interval logic | |
var interval_id; | |
function startInterval() { | |
clearInterval(interval_id); | |
interval_id = setInterval(function () { | |
console.log("No recent deploys. Restarting..."); | |
process.kill(process.pid, "SIGUSR2"); | |
}, RESTART_TIMEOUT); | |
} | |
if (cluster.isMaster) { | |
os.cpus().forEach(function() { | |
workers.push(cluster.fork()); | |
}); | |
startInterval(); | |
process.on('SIGUSR2',function() { | |
console.log("Received SIGUSR2 with " + workers.length + " workers running"); | |
console.log("Restart #" + (++start_count)); | |
startInterval(); | |
// Blank the worker list, but keep a copy for ourselves: | |
var workers_copy = workers.slice(); | |
workers = []; | |
workers_copy.forEach(function (worker) { | |
console.log("Disconnecting worker ID " + worker.id); | |
worker.disconnect(); | |
// Timeout, just in case it won't die willingly: | |
var savedTimeout = setTimeout(function () { | |
console.log("Worker ID " + worker.id + " not responding. Killing process..."); | |
worker.forced_death = true; | |
worker.destroy(); | |
}, DEATH_TIMEOUT); | |
// Worker will raise a disconnect event if it runs through its queue gracefully: | |
worker.on('disconnect', function () { | |
// Check to see if disconnect is raised because of a force kill: | |
if (worker.forced_death) { return; } | |
// Else, we just ran through our connections. Cool! | |
console.log("Worker ID " + worker.id + " ran through connections gracefully."); | |
worker.destroy(); | |
clearTimeout(savedTimeout); | |
}); | |
// Push this worker's replacement into the new worker list: | |
workers.push(cluster.fork()); | |
}); | |
}); | |
cluster.on('exit', function(worker, code, signal) { | |
// Suicide is if we're the ones who killed it: | |
if (worker.suicide) { return; } | |
// Else, this shouldn't have died. Restart: | |
workers = workers.filter(function(w) { return w.id !== worker.id; }); | |
if (!worker.reloaded) { | |
console.log('Worker ' + worker.id + ' died, forking a replacement'); | |
workers.push(cluster.fork()); | |
} | |
}); | |
} else { | |
var server = require('./app'); | |
server.listen(3000); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment