Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 81e363a

Browse filesBrowse files
legendecastargos
authored andcommitted
worker: add argv constructor option
A convenience option to populate `process.argv` in worker threads. PR-URL: #30559 Fixes: #30531 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Denys Otrishko <shishugi@gmail.com>
1 parent 2cc0482 commit 81e363a
Copy full SHA for 81e363a

File tree

Expand file treeCollapse file tree

4 files changed

+81
-3
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+81
-3
lines changed
Open diff view settings
Collapse file

‎doc/api/worker_threads.md‎

Copy file name to clipboardExpand all lines: doc/api/worker_threads.md
+7Lines changed: 7 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,9 @@ changes:
510510
- version: REPLACEME
511511
pr-url: https://github.com/nodejs/node/pull/26628
512512
description: The `resourceLimits` option was introduced.
513+
- version: REPLACEME
514+
pr-url: https://github.com/nodejs/node/pull/30559
515+
description: The `argv` option was introduced.
513516
-->
514517

515518
* `filename` {string} The path to the Worker’s main script. Must be
@@ -518,6 +521,10 @@ changes:
518521
If `options.eval` is `true`, this is a string containing JavaScript code
519522
rather than a path.
520523
* `options` {Object}
524+
* `argv` {any[]} List of arguments which would be stringified and appended to
525+
`process.argv` in the worker. This is mostly similar to the `workerData`
526+
but the values will be available on the global `process.argv` as if they
527+
were passed as CLI options to the script.
521528
* `env` {Object} If set, specifies the initial value of `process.env` inside
522529
the Worker thread. As a special value, [`worker.SHARE_ENV`][] may be used
523530
to specify that the parent thread and the child thread should share their
Collapse file

‎lib/internal/main/worker_thread.js‎

Copy file name to clipboardExpand all lines: lib/internal/main/worker_thread.js
+16-2Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ if (process.env.NODE_CHANNEL_FD) {
9292
port.on('message', (message) => {
9393
if (message.type === LOAD_SCRIPT) {
9494
const {
95+
argv,
9596
cwdCounter,
9697
filename,
9798
doEval,
@@ -115,6 +116,9 @@ port.on('message', (message) => {
115116
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
116117
loadPreloadModules();
117118
initializeFrozenIntrinsics();
119+
if (argv !== undefined) {
120+
process.argv = process.argv.concat(argv);
121+
}
118122
publicWorker.parentPort = publicPort;
119123
publicWorker.workerData = workerData;
120124

@@ -138,12 +142,22 @@ port.on('message', (message) => {
138142
port.postMessage({ type: UP_AND_RUNNING });
139143
if (doEval) {
140144
const { evalScript } = require('internal/process/execution');
141-
evalScript('[worker eval]', filename);
145+
const name = '[worker eval]';
146+
// This is necessary for CJS module compilation.
147+
// TODO: pass this with something really internal.
148+
ObjectDefineProperty(process, '_eval', {
149+
configurable: true,
150+
enumerable: true,
151+
value: filename,
152+
});
153+
process.argv.splice(1, 0, name);
154+
evalScript(name, filename);
142155
} else {
143156
// script filename
144157
// runMain here might be monkey-patched by users in --require.
145158
// XXX: the monkey-patchability here should probably be deprecated.
146-
CJSLoader.Module.runMain(process.argv[1] = filename);
159+
process.argv.splice(1, 0, filename);
160+
CJSLoader.Module.runMain(filename);
147161
}
148162
} else if (message.type === STDIO_PAYLOAD) {
149163
const { stream, chunk, encoding } = message;
Collapse file

‎lib/internal/worker.js‎

Copy file name to clipboardExpand all lines: lib/internal/worker.js
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,16 @@ class Worker extends EventEmitter {
8686
validateString(filename, 'filename');
8787
if (options.execArgv && !ArrayIsArray(options.execArgv)) {
8888
throw new ERR_INVALID_ARG_TYPE('options.execArgv',
89-
'array',
89+
'Array',
9090
options.execArgv);
9191
}
92+
let argv;
93+
if (options.argv) {
94+
if (!ArrayIsArray(options.argv)) {
95+
throw new ERR_INVALID_ARG_TYPE('options.argv', 'Array', options.argv);
96+
}
97+
argv = options.argv.map(String);
98+
}
9299
if (!options.eval) {
93100
if (!path.isAbsolute(filename) && !/^\.\.?[\\/]/.test(filename)) {
94101
throw new ERR_WORKER_PATH(filename);
@@ -158,6 +165,7 @@ class Worker extends EventEmitter {
158165
this[kPublicPort].on('message', (message) => this.emit('message', message));
159166
setupPortReferencing(this[kPublicPort], this, 'message');
160167
this[kPort].postMessage({
168+
argv,
161169
type: messageTypes.LOAD_SCRIPT,
162170
filename,
163171
doEval: !!options.eval,
Collapse file
+49Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const { Worker, isMainThread, workerData } = require('worker_threads');
5+
6+
if (isMainThread) {
7+
assert.throws(() => {
8+
new Worker(__filename, { argv: 'foo' });
9+
}, {
10+
code: 'ERR_INVALID_ARG_TYPE'
11+
});
12+
13+
[
14+
new Worker(__filename, {
15+
argv: [null, 'foo', 123, Symbol('bar')],
16+
// Asserts only if the worker is started by the test.
17+
workerData: 'assert-argv'
18+
}),
19+
new Worker(`
20+
const assert = require('assert');
21+
assert.deepStrictEqual(
22+
process.argv,
23+
[process.execPath, '[worker eval]']
24+
);
25+
`, {
26+
eval: true
27+
}),
28+
new Worker(`
29+
const assert = require('assert');
30+
assert.deepStrictEqual(
31+
process.argv,
32+
[process.execPath, '[worker eval]', 'null', 'foo', '123',
33+
String(Symbol('bar'))]
34+
);
35+
`, {
36+
argv: [null, 'foo', 123, Symbol('bar')],
37+
eval: true
38+
})
39+
].forEach((worker) => {
40+
worker.on('exit', common.mustCall((code) => {
41+
assert.strictEqual(code, 0);
42+
}));
43+
});
44+
} else if (workerData === 'assert-argv') {
45+
assert.deepStrictEqual(
46+
process.argv,
47+
[process.execPath, __filename, 'null', 'foo', '123', String(Symbol('bar'))]
48+
);
49+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.