Skip to content

Commit 78ad8b4

Browse files
jasnelltargos
authored andcommitted
workers: fix spawning from preload scripts
Fix spawning nested worker threads from preload scripts and warn about doing so. Signed-off-by: James M Snell <[email protected]> Fixes: #36531 PR-URL: #37481 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 52c0f0b commit 78ad8b4

File tree

4 files changed

+35
-4
lines changed

4 files changed

+35
-4
lines changed

doc/api/worker_threads.md

+11
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,17 @@ Calling `unref()` on a worker will allow the thread to exit if this is the only
966966
active handle in the event system. If the worker is already `unref()`ed calling
967967
`unref()` again will have no effect.
968968

969+
## Notes
970+
971+
### Launching worker threads from preload scripts
972+
973+
Take care when launching worker threads from preload scripts (scripts loaded
974+
and run using the `-r` command line flag). Unless the `execArgv` option is
975+
explicitly set, new Worker threads automatically inherit the command line flags
976+
from the running process and will preload the same preload scripts as the main
977+
thread. If the preload script unconditionally launches a worker thread, every
978+
thread spawned will spawn another until the application crashes.
979+
969980
[Addons worker support]: addons.md#addons_worker_support
970981
[ECMAScript module loader]: esm.md#esm_data_imports
971982
[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm

lib/internal/main/worker_thread.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,6 @@ port.on('message', (message) => {
119119
initializeCJSLoader();
120120
initializeESMLoader();
121121

122-
const CJSLoader = require('internal/modules/cjs/loader');
123-
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
124-
loadPreloadModules();
125-
initializeFrozenIntrinsics();
126122
if (argv !== undefined) {
127123
process.argv = process.argv.concat(argv);
128124
}
@@ -145,6 +141,11 @@ port.on('message', (message) => {
145141
};
146142
workerIo.sharedCwdCounter = cwdCounter;
147143

144+
const CJSLoader = require('internal/modules/cjs/loader');
145+
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
146+
loadPreloadModules();
147+
initializeFrozenIntrinsics();
148+
148149
if (!hasStdin)
149150
process.stdin.push(null);
150151

test/fixtures/worker-preload.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const {
2+
Worker,
3+
workerData,
4+
threadId
5+
} = require('worker_threads');
6+
7+
if (threadId < 2) {
8+
new Worker('1 + 1', { eval: true });
9+
}

test/parallel/test-preload-worker.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fixtures = require('../common/fixtures');
5+
const worker = fixtures.path('worker-preload.js');
6+
const { exec } = require('child_process');
7+
const kNodeBinary = process.argv[0];
8+
9+
10+
exec(`"${kNodeBinary}" -r "${worker}" -pe "1+1"`, common.mustSucceed());

0 commit comments

Comments
 (0)