Skip to content

Instantly share code, notes, and snippets.

@ascendantlogic
Created January 5, 2013 03:03
Show Gist options
  • Save ascendantlogic/4459463 to your computer and use it in GitHub Desktop.
Save ascendantlogic/4459463 to your computer and use it in GitHub Desktop.
Just some random node.js load balancing code I wrote about a month ago. It forks child processes for each core on the machine you're on and puts the PIDs into a workers/ directory so you can restart children with commands like "ls workers/* | xargs kill". Not guaranteed to be useful or even work right at this point, just something I spent an eve…
var http = require('http')
, path = require('path')
, os = require('os')
, fs = require('fs')
, cluster = require('cluster');
var app, logger;
var numCores = os.cpus().length;
var workerPidPath = path.join(__dirname, 'workers/');
var masterPidPath = path.join(__dirname, 'master/');
var orderlyShutdown = function(cluster, logger) {
for(var id in cluster.workers) {
cluster.workers[id].destroy();
}
logger.info("Master " + process.pid + " killed as a result of an orderly shutdown.");
fs.unlinkSync(masterPidPath + process.pid);
};
module.exports.start = function(app, logger) {
if (cluster.isMaster) {
for(var i=0; i<numCores; i++) {
cluster.fork();
}
cluster.on('fork', function(worker) {
fs.writeFileSync(workerPidPath + worker.process.pid, worker.process.pid);
logger.info("Worker " + worker.process.pid + " created");
});
cluster.on('exit', function(worker, code, signal) {
fs.unlinkSync(workerPidPath + worker.process.pid);
if (worker.suicide === false) {
logger.warn("Worker " + worker.process.pid + " killed in a disorderly fashion. Spinning up new worker.");
cluster.fork();
} else {
logger.warn("Worker " + worker.process.pid + " killed as a result of an orderly shutdown.");
}
});
process.on('SIGINT', function() {
logger.info("SIGINT RECEIVED");
orderlyShutdown(cluster, logger);
});
process.on('SIGTERM', function() {
logger.info("SIGTERM RECEIVED");
orderlyShutdown(cluster, logger);
});
logger.debug("Master process " + process.pid + " started");
fs.writeFileSync(masterPidPath + process.pid, process.pid);
} else {
http.createServer(app).listen(app.get('port'));
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment