-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Ergonomic way to move data between workers #10078
Comments
Very interesting, would be great to see something like this. While having this shape of API for the blank worker use case makes a lot of sense, for the use case where the worker itself has a "top-level" module definition, it might also make sense to simplify the interface further to some kind of top-level exports use: const worker = new Worker('./mod.mjs', { type: 'module' });
const { createNumbersArray, anotherExport } = worker.getExports(['createNumbersArray', 'anotherExport']); |
The dynamic behavior allowed by importValue()'s exportName argument makes sense in the context of shadow realms which are heavy on eval-semantics already, but I am concerned it would lend itself to a style that makes it harder for static analysis for security purposes, like for auditing WebExtensions where there's definitely problems with bad actors trying to do tricky things via obfuscated dynamism. Like, it's fine if there's always a string literal there, but the API shape feels like it would be just as idiomatic to use a variable which opens up all kinds of avenues of dynamism, and the need for code auditors to potentially re-litigate the exact same debate over about how submitted code should use the API. In particular, I can imagine developers wanting to use a for loop there. I feel like there had previously been discussion about enabling something like The downside with this alternative is of course that it would potentially do significantly more work than required if the imported script has more exported functions than the caller wants to call. Although obviously it's possible with modules to not export more than is actually desired to proxy, and this approach could arguably be beneficial to static-analysis-based auditors since it would encourage the code authors to limit their number of exports because their code would perform worse because of the wasted exports. |
This is a wider concern with string specifiers as a dynamic import mechanism. The problem would be generally solved for all forms of dynamic import (including this one) with the module expression blocks proposal. |
There are cases where blocks are handy, but I don't think they should be required to improve worker communication. Having worker code in another file is usually a benefit. |
@guybedford yeah, I agree that would be handy (although |
This comment was marked as resolved.
This comment was marked as resolved.
I don't think we should get too bogged down in the transferable issue, but I think the solution here should be the same as it would be for transferred streams. Something like: const blob = new Blob(…);
markForTransfer(blob); At this point Then, in StructuredSerializeWithTransfer, if an object is in the "marked for transfer" set, it's transferred, and removed from the set. Having one API that's transfer by default seems weird. |
I like the Have there been similar discussions of this proposal elsewhere, and in particular that have been TAG reviewed? I'm having trouble finding other examples of I should also note:
|
In chatting with @guybedford, a challenge across JavaScript runtimes right now is how to run an untrusted guest via For a host to prevent that, a parent controlling event loop is required. We can accomplish that by having a However, the ergonomics of this leave a lot to be desired; packaging re-usable code across runtimes so that some is run in a worker and some in the main thread is challenging. Setting up the communication channels in a cross-platform way is also challenging for the same reasons motivating this discussion. It seems like a version of this proposal might offer a more ergonomic way of handling this intermediary |
What problem are you trying to solve?
Right now, call-and-response communications with a worker are pretty cumbersome. Complex libraries have been created to try and make this easier.
What solutions exist today?
Message ports, and utilities like comlink.
How would you solve it?
This builds on the blank worker proposal.
ShadowRealm is now stage 3, and I think it has ideas we could borrow.
importValue
would throw if the worker is nottype: 'module'
.The export can be anything structured cloneable, but can be or can include functions.
When functions are called, the args are cloned and the function in the worker is called with those args. The return value is cloned, and used to resolve the function on the caller's side.
For example:
worker-utils.js
index.js
Anything else?
It'd be nice if certain values could be marked as "transferrable" rather than cloneable. Tranferrable streams would benefit from this too.
The text was updated successfully, but these errors were encountered: