| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
Review requested:
|
Sorry, something went wrong.
There was a problem hiding this comment.
In addition to it, we are adding new node_api_set_finalizer_error_handler public API to setup an error handler per napi_env instance which is created per each native module. Each native module can handle its finalizer JS errors on its own.
Why? This seems like a bad idea. Addons that need to handle errors should explicitly check for exceptions rather than installing semi-global handlers for that.
Sorry, something went wrong.
This is only half the truth – the significantly bigger issue is that the finalizers may run at any point during other synchronous JavaScript execution if GC happens to kick in. |
Sorry, something went wrong.
|
FWIW, in most cases, the second pass callbacks are called in the platform idle tasks queue. However, there are cases where the second pass callbacks are invoked synchronously :
I'd agree that allowing arbitrary JavaScript to run during second callbacks is a bad idea. I'm wondering if there are chances that we can call into addons with disallowing JavaScript execution to give addons a chance to release external memory, especially when the program reached the isolate's external memory limit? |
Sorry, something went wrong.
It is a "safety net" for developers who work on a big native addons. When a big team works on an addon, they individually may not know all aspects of the addon. Having an error handler per addon may help the team to weed out any accidental issues that they introduced. Otherwise, an unhandled error will cause Node.js to crash globally, and someone else in production environment must do the extra work to attribute that crash to the specific addon and notify the team. |
Sorry, something went wrong.
|
i'm also not a fan of this approach. it sounds like your issue is less about finalizer errors and more about review culture on these teams. |
Sorry, something went wrong.
This is the main goal of this PR. Without running the finalizers as a part of the GC we cannot free the native resources on-time and in some scenarios it causes a pseudo memory leak (see nodejs/node-addon-api#1140). Is your concern of running JS code as a part of finalizers as @legendecas described above? |
Sorry, something went wrong.
Agree. Having a better review culture can address some issues. Though, in real code that may have multiple levels of indirections it is practically impossible to find all places that may accidently cause JS errors thrown, unless we completely prohibit touching JS code in the finalizers. Note that our docs, samples, tests, or examples never mention or show how to handle JS errors in finalizers. Also, I do not completely understand why handling unhandled exceptions in the global process-wide level is a good and a practical thing but giving the opportunity to the native addon developers to do the same for their code is a bad practice. |
Sorry, something went wrong.
It sounds like we may need to have two classes of finalizers:
Is it correct? |
Sorry, something went wrong.
There was a problem hiding this comment.
Why does the finalizer error handler have to be a napi_value? Why not a C function pointer?
Sorry, something went wrong.
|
This PR was discussed today in Node-API meeting. The focus was mostly on whether we must introduce new "pure" finalizers.
|
Sorry, something went wrong.
|
PR #42651 adds the "pure" finalizers. |
Sorry, something went wrong.
Seeing that unhandled exceptions can be handled today from JS code, I thought that making the finalizer error handler to be a JS function will make it follow the same lines. |
Sorry, something went wrong.
|
Closing this PR since the idea of having a handler for finalizer errors seems to be unpopular. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
The issue
Currently Reference finalizers are run inside of SetImmediate.
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 of process.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:
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.