-
Notifications
You must be signed in to change notification settings - Fork 30.4k
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
node-api: run Node-API finalizers in GC second pass #42208
Conversation
Review requested:
|
@nodejs/node-api Does this require any documentation additions or new tests? |
It is changing the internal behavior - I am not sure about the docs. |
While I work on the unit test, I see that I was completely wrong about the root cause of the issue. Lines 36 to 48 in b35ee26
Converting the status of the PR to a draft for now. |
Running all finalizers in the It sounds like that in order to do it right we must:
|
We had discussed this PR in our Node-API meeting today on 3/11/2022. The key takeaways from the discussion:
Some thoughts about the finalizer error handling after the meeting:
|
I ended up removing the finalizing_queue in favor of using GC second pass as it used to be before a74a6e3 and fixing the error handing mechanism for finalizers. |
Sorry, I accidently removed the PR branch. The PR is re-created as #42515 |
The issue
Currently
Reference
finalizers are run inside ofSetImmediate
.In case if user code creates a lot of native objects in the main script, it could cause a significant memory pressure, even if the objects are properly released. This is because they are "collected" only inside of
SetImmediate
that follows the script run.See issue: nodejs/node-addon-api#1140
In the a74a6e3 commit the processing of finalizers was moved from the GC second pass to the
SetImmediate
because finalizers may throw JavaScript exceptions which can affect behavior of other functions.If the JavaScript exception is thrown inside of
SetImmediate
, then it causes an unhandled exception which can be handled process-wide with help ofprocess.on('uncaughtException', ...)
event handler.The solution
In this PR we are switching back to processing finalizers in the GC second pass which may happen any time after GC calls.
To address the issue of handling JS exceptions from finalizers we do the following in this PR:
SetImmediate
. Thus, we address the previous issue with the finalizer JS errors interrupting other functions, and align the error handling behavior withSetImmediate
.node_api_set_finalizer_error_handler
public API to setup an error handler pernapi_env
instance which is created per each native module. Each native module can handle its finalizer JS errors on its own.Tests
New test_finalizer_exception test is added to js-native-api to verify the new behavior.
All other js-native-api, node-api, and cctests are passing.
Documentation
The n-api.md documentation is updated with the new
node_api_set_finalizer_error_handler
public API.See the n-api.md for the details about the
node_api_set_finalizer_error_handler
function.