Skip to content

Commit d066db7

Browse files
toddwongMylesBorins
authored andcommitted
cluster: support windowsHide option for workers
Fixes: #17370 PR-URL: #17412 Fixes: #17370 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 51eab4b commit d066db7

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

doc/api/cluster.md

+2
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,8 @@ changes:
722722
This can be a number, or a function that takes no arguments and returns a
723723
number. By default each worker gets its own port, incremented from the
724724
master's `process.debugPort`.
725+
* `windowsHide` {boolean} Hide the forked processes console window that would
726+
normally be created on Windows systems. **Default:** `false`
725727

726728
After calling `.setupMaster()` (or `.fork()`) this settings object will contain
727729
the settings, including the default values.

lib/internal/cluster/master.js

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ function createWorkerProcess(id, env) {
127127
return fork(cluster.settings.exec, cluster.settings.args, {
128128
env: workerEnv,
129129
silent: cluster.settings.silent,
130+
windowsHide: cluster.settings.windowsHide,
130131
execArgv: execArgv,
131132
stdio: cluster.settings.stdio,
132133
gid: cluster.settings.gid,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const child_process = require('child_process');
5+
const cluster = require('cluster');
6+
7+
if (!process.argv[2]) {
8+
/* It seems Windows only allocate new console window for
9+
* attaching processes spawned by detached processes. i.e.
10+
* - If process D is spawned by process C with `detached: true`,
11+
* and process W is spawned by process D with `detached: false`,
12+
* W will get a new black console window popped up.
13+
* - If D is spawned by C with `detached: false` or W is spawned
14+
* by D with `detached: true`, no console window will pop up for W.
15+
*
16+
* So, we have to spawn a detached process first to run the actual test.
17+
*/
18+
const master = child_process.spawn(
19+
process.argv[0],
20+
[process.argv[1], '--cluster'],
21+
{ detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] });
22+
23+
const messageHandlers = {
24+
workerOnline: common.mustCall((msg) => {
25+
}),
26+
mainWindowHandle: common.mustCall((msg) => {
27+
assert.ok(/0\s*/.test(msg.value));
28+
}),
29+
workerExit: common.mustCall((msg) => {
30+
assert.strictEqual(msg.code, 0);
31+
assert.strictEqual(msg.signal, null);
32+
})
33+
};
34+
35+
master.on('message', (msg) => {
36+
const handler = messageHandlers[msg.type];
37+
assert.ok(handler);
38+
handler(msg);
39+
});
40+
41+
master.on('exit', common.mustCall((code, signal) => {
42+
assert.strictEqual(code, 0);
43+
assert.strictEqual(signal, null);
44+
}));
45+
46+
} else if (cluster.isMaster) {
47+
cluster.setupMaster({
48+
silient: true,
49+
windowsHide: true
50+
});
51+
52+
const worker = cluster.fork();
53+
worker.on('exit', (code, signal) => {
54+
process.send({ type: 'workerExit', code: code, signal: signal });
55+
});
56+
57+
worker.on('online', (msg) => {
58+
process.send({ type: 'workerOnline' });
59+
60+
let output = '0';
61+
if (process.platform === 'win32') {
62+
output = child_process.execSync(
63+
'powershell -NoProfile -c ' +
64+
`"(Get-Process -Id ${worker.process.pid}).MainWindowHandle"`,
65+
{ windowsHide: true, encoding: 'utf8' });
66+
}
67+
68+
process.send({ type: 'mainWindowHandle', value: output });
69+
worker.send('shutdown');
70+
});
71+
72+
} else {
73+
cluster.worker.on('message', (msg) => {
74+
cluster.worker.disconnect();
75+
});
76+
}

0 commit comments

Comments
 (0)