-
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
esm, loader: move to own thread #43658
Comments
@bmeck @MylesBorins could either of you speak to the impetus for this? |
Related: #31229 |
Pros and cons here: nodejs/modules#351 (comment) |
Can add to the list of package authors: I wonder, does it make sense for the loaders team to have a thread somewhere which can be subscribed to for notifications of breaking changes? All relevant discussion can happen elsewhere, the thread would be like an RSS feed. Package maintainers can opt-in to notifications of breaking or potentially exciting/disruptive changes by subscribing to that thread. Might scale better than us hoping we know a comprehensive list of all loaders. |
Since Node.js doesn't maintain anything of the sort, that sounds like a better alternative to "surprise!". It's not full-proof, though. |
We have a working Proof of Concept: https://github.com/JakobJingleheimer/worker-atomics |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Hiya! Please look right above your post to find the active WIP PR link (in the fancy GitHub callout), which was updated recently. |
I was chatting with Anna earlier today, and she mentioned the CPU and memory cost of the 2nd thread is non-trivial—effectively doubling node's basic footprint. Is that something we've already considered? Do we know of any way to mitigate that? |
If you use --loader on a single threaded application that is somewhat true
but shouldn'tbe 2x. Plenty of stuff like v8 intrinsics, c++ code, etc. are
not recreated. If the loader is shared amongst worker threads it can
actually be a net gain. Overall ability to intercept CJS and being opt-in
seems fine. If we need to save more there are ways to do so that haven't
been done since currently the worker thread impl does spin up a full node
env.
…On Fri, Oct 21, 2022, 3:53 PM Jacob Smith ***@***.***> wrote:
I was chatting with Anna earlier today, and she mentioned the CPU and
memory cost of the 2nd thread is non-trivial—effectively doubling node's
basic footprint.
Is that something we've already considered? Do we know of any way to
mitigate that?
—
Reply to this email directly, view it on GitHub
<#43658 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABZJIYVULTTYEQVPJ42AQ3WEL7F3ANCNFSM52PQG7HQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
The way this issue is framed implies that import loaders are moved off thread. In other terms, only users deliberately opting in are using a different thread. However, this is not the direction the work went and all ESM loading logic is being moved. I spoke to quite a few people over time about this and this was not brought up before today. This is a significant blocker for me as Node.js is often used in environment that are constrained by memory. At the bare minimum we should investigate:
|
I agree that we should find answers to those questions. I would hold off on adding it to the TSC agenda until we have those answers. |
Edit: I believe it was always our intention to get those numbers before landing.
This does not seem to be a straightforward answer. I can't truly measure it until the implementation is runnable (currently blocked by a V8 error). Preliminary result data from our experiment via
This very basic rough comparison suggests additional memory consumption at peak of
Preliminary results suggest there's a small initial cost when the worker initialises, but in terms of latency incurred for the work off-loaded, there's effectively none (nanoseconds).
I think this is contrary to the goals we're attempting to achieve with a separate thread (but maybe we only care about custom loaders).
The thread gracefully terminates after the last call to "public" ESMLoader. However, in the tests done so far, that coincides with node itself gracefully terminating. We could specifically test keeping node around for a while after all the ESM / loader stuff to see if the thread terminates. I'm not sure how best to go about that: |
There's also a potential benefit in moving non-custom loading off-thread as it would protect internals from prototype pollution (I think). That would argue that we should make this same refactor for CommonJS too. |
@mcollina I'm not convinced we can answer those questions before we have a fully working implementation; without data, we can only make assumptions, and I wouldn't want us to draw a conclusion over possibly baseless assumptions. |
Absolutely! I'm concerned about the addition to our startup memory footprint, as this matters for some of our usecases. I'm flagging that this might be problematic and I was surprised because it was not mentioned in the main text of the issue. A few more question:
|
In both cases, (in the current design/implementation) only if the "loaders" worker is not around (otherwise it will be re-used). |
So there is only one loaders worker for all worker threads created by Node.js? |
No, there's a separate loaders worker for each worker thread. |
I assume it should be possible to configure loader hooks per worker thread therefore this may complicate this thread. I'm also a bit skeptical to have a single loader thread for all workers as this seems to allow "leaking" data between workers which should be isolated. Also this single loader worker would be parallelism blocker. |
The comment from @targos and @JakobJingleheimer seem contradictory? |
There are 3 different threading models being considered, that I'm aware of. |
Sorry, I think #43658 (comment) is the intended behaviour (the current PR may not achieve that yet). The rationale being that workers are intended to be isolated, so their loaders' state should also be isolated/fresh. |
Quick update from our recent team meeting: We invited Gil Tayar (author/maintainer of several pertinent libraries) to discuss spawning a dedicated loaders thread per user-land thread, and he noted that will add enormous complexity to library authors (on top of the extra complexity on node's side). We decided for an initial implementation, it would be better to use a single loaders thread shared by all user-land threads and add caveats to the relevant sections of the docs. If there is sufficient appetite, we can subsequently add a configuration option (perhaps to the |
Was there any progress on not spawning any thread if no custom loaders are defined? |
Yep! nodejs/loaders#118 (comment) and I believe this should be logistically/technically possible. |
What is the problem this feature will solve?
import.meta.resolve()
For the initial implementation, the same loaders thread will be used for all user-land threads. A subsequent enhancement may add a configuration option to the
Worker
constructor to spawn its own dedicated loaders thread.What is the feature you are proposing to solve the problem?
Move loaders off-thread
What alternatives have you considered?
No response
Per direction from TSC
Following in the vein of babel: babel/babel#14025
And https://github.com/bmeck/using-node-workshop/tree/main/steps/6_async_and_blocking
The text was updated successfully, but these errors were encountered: