-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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 thread aborts on terminate if native node module has an open async handle #34567
Comments
I think this is basically looking for async versions of |
Hopefully I can represent demand from 2 of my larger native projects 😄. NodeGitI maintain https://github.com/nodegit/nodegit which I think would still overall benefit from async environment clean up hooks. In that library we leverage a separate thread pool from libuv (more information can be found here). We kind of have 2 options for enabling nodegit in worker threads:
NSFW (Node Sentinel File Watcher)I maintain https://github.com/axosoft/nsfw.git. This is a custom built recursive file watcher that replaces the standard node capabilities off thread and at an OS level. It implements linux, osx, and windows file watching and requires at least one internal thread. When file events are arriving, depending on the scale of the operation occurring in the folder you're watching, you might have to do a lot of synchronous work in javascript to find an important event. It would be nice if we could leverage NSFW in a worker thread instead of on the main thread, so that we could handle those events and do more javascript parsing of what's important off main thread and only communicate interesting changes back to the main thread. Again my example here is imagine you're a text editor built in Electron. If you're watching an entire directory tree, you might care about events like changes to I think eliminating the potential double hop of retrieving events in the main thread, shipping them off to a worker thread to be parsed, and then having them come back from the worker thread for response can be limiting architecturally. NSFW also suffers a similar abort crash through it's use of N-API. I'd love to see that resolved as well. Hopefully these help establish why it could make sense to leverage async behavior even in worker threads. I believe that even though I'm mentioning Electron, providing the async clean up at this level would allow |
Sometimes addons need to perform cleanup actions, for example closing libuv handles or waiting for requests to finish, that cannot be performed synchronously. Add C++ API and N-API functions that allow providing such asynchronous cleanup hooks. Fixes: nodejs#34567
#34572 should provide APIs that enable this, feel free to take a look :) |
First I just want to thank you for such a quick response and an unexpectedly quick solution. Ok I have read over those changes. If I'm understanding everything correctly, the async cleanup hook will provide a finalize function pointer to If that's what we're looking at I think that would solve my use-case. One more question for you, will this keep the v8 context alive until the Part of doing async work is frequently built around persistent handles of v8 objects that have external pointers associated with them (like ObjectWrap). The usual flow is to persist the object that the pointer is attached to long enough for the async work to complete the execute thread. If any of those objects were to be marked for GC while the execute thread is in motion, but before the library has finished shutting down its async work, that would definitely lead to a segfault. |
@implausible Just to avoid misunderstandings,
Yes. However, you are not allowed to perform any calls into JS anymore.
The persistent handles remain alive, but keep in mind that the cleanup hook should also tear all of them down at some point before it is finished, otherwise you’ll end up with a memory leak. |
Perfect, I can understand all of that 😄! Thank you again for your help. |
Sometimes addons need to perform cleanup actions, for example closing libuv handles or waiting for requests to finish, that cannot be performed synchronously. Add C++ API and N-API functions that allow providing such asynchronous cleanup hooks. Fixes: #34567 PR-URL: #34572 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com>
Sometimes addons need to perform cleanup actions, for example closing libuv handles or waiting for requests to finish, that cannot be performed synchronously. Add C++ API and N-API functions that allow providing such asynchronous cleanup hooks. Fixes: #34567 PR-URL: #34572 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com>
Sometimes addons need to perform cleanup actions, for example closing libuv handles or waiting for requests to finish, that cannot be performed synchronously. Add C++ API and N-API functions that allow providing such asynchronous cleanup hooks. Fixes: #34567 PR-URL: #34572 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com>
v14.6.0, v12.14.1
4.15.0-1091-oem #101-Ubuntu SMP Thu Jun 25 17:55:29 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
worker_threads
What steps will reproduce the bug?
I have opened up a repository here that can be used to reliably crash node. Follow the steps in
README.md
to replicate.How often does it reproduce? Is there a required condition?
This reproduces so long as a native node module has an active async handle for async completion.
What is the expected behavior?
Worker thread should not terminate until all handles are cleaned up. Modules should be able to exit gracefully when terminate is requested.
What do you see instead?
The text was updated successfully, but these errors were encountered: