public
Created — forked from wankdanker/SimpleCluster.js

A simple cluster module that re-spawns child processes that have died. Also reloads child processes when `require()`d script files have changed.

  • Download Gist
SimpleCluster.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
/*jslint node: true, maxerr: 50, indent: 4 */
 
"use strict";
 
var clusterInstance;
 
var SimpleCluster = module.exports = function () {
//there should only be one instance of this per process
if (clusterInstance) {
return clusterInstance;
} else {
clusterInstance = this;
}
 
var cluster = require('cluster'),
os = require('os'),
self = this;
 
self.cluster = cluster;
self.watchedScripts = {};
self.workers = {};
 
/*
* forkWorker()
*
* Fork a new worker and set up the callback for receiving required scripts
*
*/
self.forkWorker = function () {
var worker = cluster.fork();
 
self.workers[worker.pid] = worker;
 
worker.on('message', function (msg) {
if (msg.cmd && msg.cmd === 'registerScripts') {
 
(msg.data || []).forEach(function (scriptPath) {
self.maybeWatchFile(scriptPath);
});
}
});
};
 
/*
* maybeWatchFile(path)
*
* Conditionally watch a file if we are not already watching it.
*
*/
self.maybeWatchFile = function (path) {
//check to see if we are already watching this script;
if (!self.watchedScripts.hasOwnProperty(path)) {
self.watchFile(path);
}
};
 
/*
* watchFile(path)
*
* Watch a file and restart workers when it has changed
*
*/
self.watchFile = function (path) {
self.watchedScripts[path] = true;
 
require('fs').watchFile(path, function (curr, prev) {
if (curr.mtime !== prev.mtime) {
//file has been modified; reload workers
 
self.restartWorkers();
}
});
};
 
/*
* restartWorkers()
*
* Restart all workers
*/
self.restartWorkers = function () {
var pid, oldWorkers, worker;
 
oldWorkers = self.workers;
self.workers = {};
 
for (pid in oldWorkers) {
if (oldWorkers.hasOwnProperty(pid)) {
worker = oldWorkers[pid];
 
worker.kill();
self.forkWorker();
}
}
};
 
/*
* start()
*
* Start the cluster
*
*/
self.start = function () {
if (cluster.isMaster) {
os.cpus().forEach(function () {
self.forkWorker();
});
 
process.on('death', function (worker) {
delete self.workers[worker.pid];
 
self.forkWorker();
});
} else {
setInterval(function () {
process.send({
cmd : 'registerScripts',
data : Object.keys(require.cache)
});
}, 2000);
}
};
};
 
module.exports.start = function () {
var c = new SimpleCluster();
c.start();
 
return c;
};
server.js
JavaScript
1 2 3 4 5 6 7 8 9
var cluster = require('simplecluster').start();
 
//sorry for not having just cluster.isMaster
if (cluster.cluster.isMaster) {
//do master stuff if anything at all
return;
}
 
//do child process stuff

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.