Skip to content

Instantly share code, notes, and snippets.

@applideveloper
Forked from yosuke-furukawa/graceful.js
Created February 5, 2016 05:29
Show Gist options
  • Select an option

  • Save applideveloper/58d658c775a2d2cac7c2 to your computer and use it in GitHub Desktop.

Select an option

Save applideveloper/58d658c775a2d2cac7c2 to your computer and use it in GitHub Desktop.
コードの変更をキャッチして、GracefulなRestartをする方法
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length / 2;
var numWorkers = numCPUs <= 1 ? 2 : numCPUs;
var watch = require('watch');
var domain = require('domain');
var util = require('util');
var forceKilledWorkers = {};
// cluster destroy if timeout.
var destroy = function() {
if (cluster.isWorker) {
var timeout = setTimeout(function() {cluster.worker.destroy();}, 120000);
forceKilledWorkers[cluster.worker.id] = timeout;
}
};
var forkWorkers = function(num) {
var forkDomain = domain.create();
forkDomain.on('error', function(error) {
util.log("error occured when starting new workers.");
util.log(error);
});
forkDomain.run(function(){
for (var i = 0; i < num; i++) {
cluster.fork();
}
});
};
var disconnectCluster = function() {
var disconnectDomain = domain.create();
disconnectDomain.on('error', function(error) {
util.log("error occured when disconnecting new workers.");
util.log(error);
destroy();
});
disconnectDomain.run(function() {
cluster.disconnect();
});
};
var respawnWorkers = function(num) {
disconnectCluster();
forkWorkers(num);
};
watch.createMonitor(__dirname, function (monitor) {
monitor.on("created", function (f, stat) {
respawnWorkers(numWorkers);
});
monitor.on("changed", function (f, curr, prev) {
respawnWorkers(numWorkers);
});
monitor.on("removed", function (f, stat) {
respawnWorkers(numWorkers);
});
});
if (cluster.isMaster) {
forkWorkers(numWorkers);
cluster.on('disconnect', function(worker) {
util.log("worker("+worker.id+").disconnect " + worker.process.pid);
});
cluster.on('exit', function(worker, code, signal) {
if (!worker.suicide) {
cluster.fork();
} else {
util.log("worker("+worker.id+") is suicide.");
}
var timeout = forceKilledWorkers[worker.id];
if (timeout) {
clearTimeout(timeout);
delete forceKilledWorkers[worker.id];
}
util.log("worker("+worker.id+").exit " + worker.process.pid);
});
cluster.on('fork', function(worker) {
util.log("worker("+worker.id+").fork");
});
cluster.on('online', function(worker) {
util.log("worker("+worker.id+").online " + worker.process.pid);
});
cluster.on('listening', function(worker, address) {
util.log("worker("+worker.id+").listening " + address.address + ":" + address.port);
});
} else if (cluster.isWorker) {
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end("<html><body><h1>Hello World.</h1></body></html>\n");
});
server.listen(3000);
server.on('close', function() { process.exit(); });
} else {
util.log("unsupported cluster.");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment