-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
worker_threads: worker.postMessage does not get executed without exiting synchronous call stack #25630
Comments
Can you post a minimal but complete test case? Sending from the main thread should work without returning control to the event loop. (Receiving it in the worker is a different matter, of course; JS code is not interruptible.) |
ping @sbalko – can you provide a test case, or steps to reproduce? |
Attached are two testcases (sorry they aren't minimal, but the relevant diff between Both testcases do a The relevant part of the diff of
Running
I'm not sure what's going on here - one possibility is that the child doesn't receive the message in the first case. Alternatively, maybe it does but Note that in browsers both testcases work. Tested on 12.2.0. |
repro 'use strict';
const { Worker, isMainThread } = require('worker_threads');
if (isMainThread) {
const worker = new Worker(__filename);
while (true) {}
} else {
console.log('alive!'); // never prints
} |
That's not unexpected, or is it? The worker doesn't print the message itself, it sends it to the main thread which prints it on the worker's behalf - but only when the main thread isn't blocked, of course. Making the main thread interruptible isn't impossible ( Since (Having said all that, your test case doesn't really match what the OP describes, if I read it right. That's about postMessage-ing from the main thread to the worker.) |
I’ll take a look at the test cases here, but in @devsnek’s case I would consider this expected behaviour, yes. There’s no point at which the main thread would reasonably call the event handler. Browsers also don’t emit the event in a single-threaded version of your reproduction, so it’s definetely a bit more complicated: {
const { port1, port2 } = new MessageChannel();
port1.onmessage = (data) => console.log('message', data)
port2.postMessage('foo')
while (true) {}
} |
why do we post back to the main thread to use stdout? is it to make sure logs don't get muddled together? if that's the problem, can we put console on the bg thread or something? not having console if loops happen is a serious problem, as evidenced by the messages in this issue if nothing else. your codeblock seems like expected behaviour to me, these events aren't supposed to fire synchronously. @bnoordhuis i had the following code: if (isMainThread) {
const worker = new Worker(__filename);
worker.postMessage('hi!');
while (true) {}
} else {
parentPort.on('message', (data) => {
console.log(data);
require('fs').writeFileSync('./worker_data', data);
});
} which i reduced to what i posted above, since the |
I'm going to remove the |
Fixes: nodejs#25630 Signed-off-by: James M Snell <[email protected]>
Fixes: nodejs#25630 Signed-off-by: James M Snell <[email protected]>
Fixes: #25630 Signed-off-by: James M Snell <[email protected]> PR-URL: #38658 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
Fixes: #25630 Signed-off-by: James M Snell <[email protected]> PR-URL: #38658 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
Fixes: #25630 Signed-off-by: James M Snell <[email protected]> PR-URL: #38658 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
Fixes: #25630 Signed-off-by: James M Snell <[email protected]> PR-URL: #38658 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
Fixes: #25630 Signed-off-by: James M Snell <[email protected]> PR-URL: #38658 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
I am playing with node's worker_threads, running Emscripten-generated multi-threaded code in this way. From what I can see, the worker's
will not get triggered, if the main thread calls
worker.postMessage(...)
without "unwinding the stack" (ie., returning control to node's event loop). Unfortunately, this is exactly the kind of code that Emscripten generates: the main thread will useAtomics.wait(...)
to wait for its child threads (workers) to complete, but it will not actually return control to node.Note that the
Worker.postMessage(...)
semantics is insofar different from howpostMessage
works in browsers, which gets executed immediately, ie., WITHOUT returning control to the browser.This may be related to #21417.
The text was updated successfully, but these errors were encountered: