forked from fictorial/jefe
/
pool.js
76 lines (58 loc) · 1.76 KB
/
pool.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
var
sys = require("sys"),
spawn = require("child_process").spawn,
events = require("events");
/**
* A pool of child processes.
* Emits `spawn` when a child is spawned.
*
* @param {String} toRun The program to spawn and run.
* Defaults to `process.argv[0]`.
* @param {Array} args Arguments to `toRun`. Defaults to `[]`.
* @param {Object} options Options for the configuring the pool.
* `minProcs` and `maxProcs` (default: 1, 4) represent the desired
* size range of the pool.
*/
function ChildPool(toRun, args, options) {
events.EventEmitter.call(this);
this.pool = [];
this.toRun = toRun || process.argv[0];
this.args = args || [];
var opts = options || {};
this.minProcs = opts.minProcs || 1;
this.maxProcs = opts.maxProcs || 4;
if (this.minProcs <= 0 ||
this.maxProcs <= 0 ||
this.minProcs > this.maxProcs)
throw new Error("invalid minProcs/maxProcs value(s)");
while (this.pool.length < this.minProcs)
this._spawnOne();
}
sys.inherits(ChildPool, events.EventEmitter);
exports.ChildPool = ChildPool;
ChildPool.prototype.size = function () {
return this.pool.length;
};
ChildPool.prototype._spawnOne = function () {
var childProc = spawn(this.toRun, this.args);
this.pool.push(childProc);
var self = this;
childProc.addListener("exit", function (code) {
self.pool.splice(self.indexOf(childProc.pid), 1);
});
this.emit("spawn", childProc);
};
ChildPool.prototype.indexOf = function (pid) {
for (var i=0, n=this.pool.length; i<n; ++i) {
if (this.pool[i].pid == pid)
return i;
}
return -1;
};
ChildPool.prototype.spawnAnotherIfAllowed = function () {
if (this.pool.length < this.maxProcs)
this._spawnOne();
};
ChildPool.prototype.forEach = function (fn) {
this.pool.forEach(fn);
};