Created
February 7, 2014 05:41
-
-
Save jfensign/8857862 to your computer and use it in GitHub Desktop.
Generic Node.js cluster implementation.
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') | |
//Console Styling | |
, Colors = require('colors') | |
//Total number of CPUs | |
, CPU_Count = require('os').cpus().length | |
//Timeouts for handling erroneous child-process spawning | |
, TimeOuts = [] | |
//Number of worker processes | |
, WorkerC = 0 | |
//Log errors (an alert/logging mechanism belongs here) | |
, LogError = function(e) { | |
console.log(e.stack); | |
} | |
//Server file | |
, Server = require("./Server") | |
//Called when a child-process fails to start | |
, onTimeout = function() { | |
console.log("%s", "Unable to start child process." .red); | |
process.exit(1); | |
} | |
//Create a worker | |
, newWorker = function() { | |
Cluster.fork(); | |
WorkerC++; | |
return; | |
} | |
//Kill a worker | |
, killWorker = function(worker, code, signal, cb) { | |
clearTimeout(TimeOuts[worker.id]); | |
WorkerC--; | |
console.log("Worker %s killed by:\nPOSIX: %s\nREPL Code: %s" .red | |
, worker.id | |
, (signal || null) | |
, (code || null)); | |
return cb(); | |
}; | |
/* | |
* Handle Master Process * | |
*/ | |
if(Cluster.isMaster) { | |
do { | |
if(WorkerC === 0) | |
console.log("%d CPUs available.".blue, CPU_Count); | |
newWorker(); | |
if(WorkerC === CPU_Count-1) | |
console.log("Application state changed from %s to %s", "Starting".yellow, "Started".green); | |
} while (WorkerC < CPU_Count-1); //Leave a CPU available for ad-hoc jobs in application | |
/* | |
* Cluster Events * | |
*/ | |
Cluster | |
.on('fork', function(worker) { | |
TimeOuts[worker.id] = setTimeout(onTimeout, 2000); | |
}) | |
.on('online', function(worker) { | |
clearTimeout(TimeOuts[worker.id]); | |
console.log("Worker %s with PID %s started".yellow | |
, worker.id | |
, worker.process.pid); | |
}) | |
.on('listening', function(worker, address) { | |
console.log("Worker %s with PID %s bound to: %s:%s".green | |
, worker.id | |
, worker.process.pid | |
, address.address | |
, address.port); | |
}) | |
.on('disconnect', function(worker, code, signal) { | |
console.log("Worker %s with PID %s killed\ncode: %s\nsignal: %s".green | |
, worker.id | |
, worker.process.pid | |
, code | |
, signal); | |
}) | |
.on('exit', function(worker, code, signal) { | |
killWorker(worker, code, signal, newWorker); | |
}); | |
} | |
else { | |
/* | |
* Handle Child Processes * | |
*/ | |
if(Cluster.isWorker) { | |
/* | |
* Instantiate App Server * | |
*/ | |
var | |
server = new Server(); | |
/* | |
* Listen for Requests (assumes server has a listen method)* | |
*/ | |
server.listen(); | |
/* | |
* Server Events * | |
*/ | |
server.on('clientError', LogError); | |
/* | |
* Process Events * | |
*/ | |
process.on('uncaughtException', LogError); | |
process.on('exit', LogError); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment