Skip to content

Instantly share code, notes, and snippets.

@baudehlo
Created September 9, 2014 19:38
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save baudehlo/c4d00a78720b85171237 to your computer and use it in GitHub Desktop.
Save baudehlo/c4d00a78720b85171237 to your computer and use it in GitHub Desktop.
"use strict";
var cluster = require("cluster");
if (process.env.NODE_ENV == 'production' && cluster.isMaster) {
// this is the master control process
console.log("Control process running: PID=" + process.pid);
// fork as many times as we have CPUs
var numCPUs = process.env.NPROCS || require("os").cpus().length;
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
// handle unwanted worker exits
cluster.on("exit", function(worker, code, signal) {
var exit_code = worker.process.exitCode;
if (!worker.suicide) {
console.log("Error: Worker crashed with exit code: " + code + "/" + exit_code + ", signal: " + signal + ". Spawning a replacement.");
cluster.fork();
}
});
// I'm using the SIGUSR2 signal to listen for reload requests
// you could, instead, use file watcher logic, or anything else
process.on("SIGUSR2", function() {
console.log("SIGUSR2 received, reloading workers");
// delete the cached module, so we can reload the app
delete require.cache[require.resolve("./app")];
// only reload one worker at a time
// otherwise, we'll have a time when no request handlers are running
var i = 0;
var workers = Object.keys(cluster.workers);
var f = function() {
if (i == workers.length) return;
console.log("Killing " + workers[i]);
var worker = cluster.workers[workers[i]];
worker.disconnect();
var disconnect_received = false;
worker.on("disconnect", function() {
disconnect_received = true;
console.log("Shutdown complete");
var dead = false;
var timer = setTimeout(function () {
if (!dead) {
console.log("Worker " + workers[i] + " failed to shutdown. Killing.");
worker.kill();
}
}, 30000);
worker.on("exit", function () { dead = true; clearTimeout(timer); });
});
var timer = setTimeout(function () {
if (!disconnect_received) {
console.log("Disconnect never received by worker. Killing.");
worker.kill();
}
}, 30000);
var newWorker = cluster.fork();
newWorker.on("listening", function() {
console.log("Replacement worker online.");
i++;
f();
});
}
f();
});
} else {
var app = require("./app");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment