Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit d287b8e

Browse files
cjihrigindutny
authored andcommitted
cluster: support options in Worker constructor
This commit moves some common Worker code into the constructor via support for an options argument. Reviewed-By: Fedor Indutny <fedor@indutny.com>
1 parent 4b59db0 commit d287b8e

File tree

2 files changed

+103
-40
lines changed

2 files changed

+103
-40
lines changed

lib/cluster.js

+54-40
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,24 @@ cluster.isWorker = ('NODE_UNIQUE_ID' in process.env);
3535
cluster.isMaster = (cluster.isWorker === false);
3636

3737

38-
function Worker() {
39-
if (!(this instanceof Worker)) return new Worker;
38+
function Worker(options) {
39+
if (!(this instanceof Worker))
40+
return new Worker(options);
41+
4042
EventEmitter.call(this);
43+
44+
if (!util.isObject(options))
45+
options = {};
46+
4147
this.suicide = undefined;
42-
this.state = 'none';
43-
this.id = 0;
48+
this.state = options.state || 'none';
49+
this.id = options.id | 0;
50+
51+
if (options.process) {
52+
this.process = options.process;
53+
this.process.on('error', this.emit.bind(this, 'error'));
54+
this.process.on('message', this.emit.bind(this, 'message'));
55+
}
4456
}
4557
util.inherits(Worker, EventEmitter);
4658

@@ -190,26 +202,6 @@ if (cluster.isMaster)
190202
else
191203
workerInit();
192204

193-
194-
function createWorkerExecArgv(masterExecArgv, worker) {
195-
var args = masterExecArgv.slice();
196-
var debugPort = process.debugPort + worker.id;
197-
var hasDebugArg = false;
198-
199-
for (var i = 0; i < args.length; i++) {
200-
var match = args[i].match(/^(--debug|--debug-brk)(=\d+)?$/);
201-
if (!match) continue;
202-
args[i] = match[1] + '=' + debugPort;
203-
hasDebugArg = true;
204-
}
205-
206-
if (!hasDebugArg)
207-
args = ['--debug-port=' + debugPort].concat(args);
208-
209-
return args;
210-
}
211-
212-
213205
function masterInit() {
214206
cluster.workers = {};
215207

@@ -278,21 +270,46 @@ function masterInit() {
278270
});
279271
};
280272

281-
var ids = 0;
282-
cluster.fork = function(env) {
283-
cluster.setupMaster();
284-
var worker = new Worker;
285-
worker.id = ++ids;
273+
function createWorkerProcess(id, env) {
286274
var workerEnv = util._extend({}, process.env);
275+
var execArgv = cluster.settings.execArgv.slice();
276+
var debugPort = process.debugPort + id;
277+
var hasDebugArg = false;
278+
287279
workerEnv = util._extend(workerEnv, env);
288-
workerEnv.NODE_UNIQUE_ID = '' + worker.id;
289-
worker.process = fork(cluster.settings.exec, cluster.settings.args, {
280+
workerEnv.NODE_UNIQUE_ID = '' + id;
281+
282+
for (var i = 0; i < execArgv.length; i++) {
283+
var match = execArgv[i].match(/^(--debug|--debug-brk)(=\d+)?$/);
284+
285+
if (match) {
286+
execArgv[i] = match[1] + '=' + debugPort;
287+
hasDebugArg = true;
288+
}
289+
}
290+
291+
if (!hasDebugArg)
292+
execArgv = ['--debug-port=' + debugPort].concat(execArgv);
293+
294+
return fork(cluster.settings.exec, cluster.settings.args, {
290295
env: workerEnv,
291296
silent: cluster.settings.silent,
292-
execArgv: createWorkerExecArgv(cluster.settings.execArgv, worker),
297+
execArgv: execArgv,
293298
gid: cluster.settings.gid,
294299
uid: cluster.settings.uid
295300
});
301+
}
302+
303+
var ids = 0;
304+
305+
cluster.fork = function(env) {
306+
cluster.setupMaster();
307+
var id = ++ids;
308+
var workerProcess = createWorkerProcess(id, env);
309+
var worker = new Worker({
310+
id: id,
311+
process: workerProcess
312+
});
296313
worker.process.once('exit', function(exitCode, signalCode) {
297314
worker.suicide = !!worker.suicide;
298315
worker.state = 'dead';
@@ -307,8 +324,6 @@ function masterInit() {
307324
cluster.emit('disconnect', worker);
308325
delete cluster.workers[worker.id];
309326
});
310-
worker.process.on('error', worker.emit.bind(worker, 'error'));
311-
worker.process.on('message', worker.emit.bind(worker, 'message'));
312327
worker.process.on('internalMessage', internal(worker, onmessage));
313328
process.nextTick(function() {
314329
cluster.emit('fork', worker);
@@ -447,20 +462,19 @@ function workerInit() {
447462

448463
// Called from src/node.js
449464
cluster._setupWorker = function() {
450-
var worker = new Worker;
465+
var worker = new Worker({
466+
id: +process.env.NODE_UNIQUE_ID | 0,
467+
process: process,
468+
state: 'online'
469+
});
451470
cluster.worker = worker;
452-
worker.id = +process.env.NODE_UNIQUE_ID | 0;
453-
worker.state = 'online';
454-
worker.process = process;
455471
process.once('disconnect', function() {
456472
if (!worker.suicide) {
457473
// Unexpected disconnect, master exited, or some such nastiness, so
458474
// worker exits immediately.
459475
process.exit(0);
460476
}
461477
});
462-
worker.process.on('error', worker.emit.bind(worker, 'error'));
463-
worker.process.on('message', worker.emit.bind(worker, 'message'));
464478
process.on('internalMessage', internal(worker, onmessage));
465479
send({ act: 'online' });
466480
function onmessage(message, handle) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
23+
// test-cluster-worker-constructor.js
24+
// validates correct behavior of the cluster.Worker constructor
25+
26+
var common = require('../common');
27+
var assert = require('assert');
28+
var cluster = require('cluster');
29+
var worker;
30+
31+
worker = new cluster.Worker();
32+
assert.equal(worker.suicide, undefined);
33+
assert.equal(worker.state, 'none');
34+
assert.equal(worker.id, 0);
35+
assert.equal(worker.process, undefined);
36+
37+
worker = new cluster.Worker({
38+
id: 3,
39+
state: 'online',
40+
process: process
41+
});
42+
assert.equal(worker.suicide, undefined);
43+
assert.equal(worker.state, 'online');
44+
assert.equal(worker.id, 3);
45+
assert.equal(worker.process, process);
46+
47+
worker = cluster.Worker.call({}, {id: 5});
48+
assert(worker instanceof cluster.Worker);
49+
assert.equal(worker.id, 5);

0 commit comments

Comments
 (0)