-
Notifications
You must be signed in to change notification settings - Fork 2
/
hellojoe.js
83 lines (69 loc) · 2.67 KB
/
hellojoe.js
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
var cluster = require("cluster");
var child = require("child_process");
var merge = require("merge");
var log = require("winston");
var defaultCores = require("os").cpus().length;
function serve(options, app) {
var i, startTimes = {}, failures = 0;
options = merge({
cores: defaultCores,
retryThreshold: 23,
retryDelay: 10000,
failureThreshold: 5000
}, options);
function pid(worker) {
return options.worker ? worker.pid : worker.process.pid;
}
function spawnMore() {
var worker;
if (options.worker) {
worker = child.fork(options.worker, options.workerArgs);
log.debug("Spawning worker %s as child process: %j %j", pid(worker), options.worker, options.workerArgs);
} else {
worker = cluster.fork();
log.debug("Spawning worker in cluster:", pid(worker));
}
startTimes[pid(worker)] = Date.now();
if (!options.worker) {
worker.on("listening", function (addr) {
return log.info("Process", pid(worker), "is now listening on", addr.address + ":" + addr.port);
});
}
// Enable Erlang mode
worker.on("exit", function (code, signal) {
var replacement, lifetime = Date.now() - startTimes[pid(worker)];
delete startTimes[pid(worker)];
if (worker.suicide) {
log.info("Worker", pid(worker), "terminated voluntarily.");
return;
}
log.info("Process", pid(worker), "terminated with signal", signal, "code", code + "; restarting.");
if (lifetime < options.failureThreshold) {
failures++;
} else {
failures = 0;
}
if (failures > options.retryThreshold) {
log.warn(failures + " consecutive failures; pausing for", options.retryDelay + "ms before respawning.");
}
setTimeout(function () {
replacement = spawnMore();
replacement.on("online", function () {
return log.info("Process", replacement.process.pid, "has successfully replaced", pid(worker));
});
}, (failures > options.retryThreshold) ? options.retryDelay : 0);
});
return worker;
}
if (cluster.isMaster) {
for (i = 0; i < options.cores; i++) {
spawnMore();
}
log.info("Spawned", options.cores, options.worker ? "worker processes." : "server instances.");
} else {
log.handleExceptions();
options.worker || app();
}
}
exports.serve = serve;
//# sourceMappingURL=hellojoe.js.map