summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlegendecas <legendecas@gmail.com>2019-11-21 00:55:36 +0800
committerAnna Henningsen <anna@addaleax.net>2019-12-03 23:44:10 +0100
commit3ebae6cf1b20ce104423214d75c3c84129a8f141 (patch)
tree12fd6bcfb86f17d050e4c04402c4ab188bb8cd5e
parenta025c5a8745637aa5f6e06acab0c15461a920d8e (diff)
downloadandroid-node-v8-3ebae6cf1b20ce104423214d75c3c84129a8f141.tar.gz
android-node-v8-3ebae6cf1b20ce104423214d75c3c84129a8f141.tar.bz2
android-node-v8-3ebae6cf1b20ce104423214d75c3c84129a8f141.zip
worker: add argv constructor option
A convenience option to populate `process.argv` in worker threads. PR-URL: https://github.com/nodejs/node/pull/30559 Fixes: https://github.com/nodejs/node/issues/30531 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Denys Otrishko <shishugi@gmail.com>
-rw-r--r--doc/api/worker_threads.md7
-rw-r--r--lib/internal/main/worker_thread.js18
-rw-r--r--lib/internal/worker.js10
-rw-r--r--test/parallel/test-worker-process-argv.js49
4 files changed, 81 insertions, 3 deletions
diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md
index b334a1091b..a93bd5422e 100644
--- a/doc/api/worker_threads.md
+++ b/doc/api/worker_threads.md
@@ -510,6 +510,9 @@ changes:
- version: v13.2.0
pr-url: https://github.com/nodejs/node/pull/26628
description: The `resourceLimits` option was introduced.
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/30559
+ description: The `argv` option was introduced.
-->
* `filename` {string} The path to the Worker’s main script. Must be
@@ -518,6 +521,10 @@ changes:
If `options.eval` is `true`, this is a string containing JavaScript code
rather than a path.
* `options` {Object}
+ * `argv` {any[]} List of arguments which would be stringified and appended to
+ `process.argv` in the worker. This is mostly similar to the `workerData`
+ but the values will be available on the global `process.argv` as if they
+ were passed as CLI options to the script.
* `env` {Object} If set, specifies the initial value of `process.env` inside
the Worker thread. As a special value, [`worker.SHARE_ENV`][] may be used
to specify that the parent thread and the child thread should share their
diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js
index 95fa3026fd..97b55ac769 100644
--- a/lib/internal/main/worker_thread.js
+++ b/lib/internal/main/worker_thread.js
@@ -92,6 +92,7 @@ if (process.env.NODE_CHANNEL_FD) {
port.on('message', (message) => {
if (message.type === LOAD_SCRIPT) {
const {
+ argv,
cwdCounter,
filename,
doEval,
@@ -115,6 +116,9 @@ port.on('message', (message) => {
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
loadPreloadModules();
initializeFrozenIntrinsics();
+ if (argv !== undefined) {
+ process.argv = process.argv.concat(argv);
+ }
publicWorker.parentPort = publicPort;
publicWorker.workerData = workerData;
@@ -143,12 +147,22 @@ port.on('message', (message) => {
port.postMessage({ type: UP_AND_RUNNING });
if (doEval) {
const { evalScript } = require('internal/process/execution');
- evalScript('[worker eval]', filename);
+ const name = '[worker eval]';
+ // This is necessary for CJS module compilation.
+ // TODO: pass this with something really internal.
+ ObjectDefineProperty(process, '_eval', {
+ configurable: true,
+ enumerable: true,
+ value: filename,
+ });
+ process.argv.splice(1, 0, name);
+ evalScript(name, filename);
} else {
// script filename
// runMain here might be monkey-patched by users in --require.
// XXX: the monkey-patchability here should probably be deprecated.
- CJSLoader.Module.runMain(process.argv[1] = filename);
+ process.argv.splice(1, 0, filename);
+ CJSLoader.Module.runMain(filename);
}
} else if (message.type === STDIO_PAYLOAD) {
const { stream, chunk, encoding } = message;
diff --git a/lib/internal/worker.js b/lib/internal/worker.js
index 621dfa7769..fb033b2472 100644
--- a/lib/internal/worker.js
+++ b/lib/internal/worker.js
@@ -82,9 +82,16 @@ class Worker extends EventEmitter {
validateString(filename, 'filename');
if (options.execArgv && !ArrayIsArray(options.execArgv)) {
throw new ERR_INVALID_ARG_TYPE('options.execArgv',
- 'array',
+ 'Array',
options.execArgv);
}
+ let argv;
+ if (options.argv) {
+ if (!ArrayIsArray(options.argv)) {
+ throw new ERR_INVALID_ARG_TYPE('options.argv', 'Array', options.argv);
+ }
+ argv = options.argv.map(String);
+ }
if (!options.eval) {
if (!path.isAbsolute(filename) && !/^\.\.?[\\/]/.test(filename)) {
throw new ERR_WORKER_PATH(filename);
@@ -154,6 +161,7 @@ class Worker extends EventEmitter {
this[kPublicPort].on('message', (message) => this.emit('message', message));
setupPortReferencing(this[kPublicPort], this, 'message');
this[kPort].postMessage({
+ argv,
type: messageTypes.LOAD_SCRIPT,
filename,
doEval: !!options.eval,
diff --git a/test/parallel/test-worker-process-argv.js b/test/parallel/test-worker-process-argv.js
new file mode 100644
index 0000000000..ebdebe02ab
--- /dev/null
+++ b/test/parallel/test-worker-process-argv.js
@@ -0,0 +1,49 @@
+'use strict';
+const common = require('../common');
+const assert = require('assert');
+const { Worker, isMainThread, workerData } = require('worker_threads');
+
+if (isMainThread) {
+ assert.throws(() => {
+ new Worker(__filename, { argv: 'foo' });
+ }, {
+ code: 'ERR_INVALID_ARG_TYPE'
+ });
+
+ [
+ new Worker(__filename, {
+ argv: [null, 'foo', 123, Symbol('bar')],
+ // Asserts only if the worker is started by the test.
+ workerData: 'assert-argv'
+ }),
+ new Worker(`
+ const assert = require('assert');
+ assert.deepStrictEqual(
+ process.argv,
+ [process.execPath, '[worker eval]']
+ );
+ `, {
+ eval: true
+ }),
+ new Worker(`
+ const assert = require('assert');
+ assert.deepStrictEqual(
+ process.argv,
+ [process.execPath, '[worker eval]', 'null', 'foo', '123',
+ String(Symbol('bar'))]
+ );
+ `, {
+ argv: [null, 'foo', 123, Symbol('bar')],
+ eval: true
+ })
+ ].forEach((worker) => {
+ worker.on('exit', common.mustCall((code) => {
+ assert.strictEqual(code, 0);
+ }));
+ });
+} else if (workerData === 'assert-argv') {
+ assert.deepStrictEqual(
+ process.argv,
+ [process.execPath, __filename, 'null', 'foo', '123', String(Symbol('bar'))]
+ );
+}