Uh oh!
There was an error while loading. Please reload this page.
feat: add support for nogc types via BasicEnv - #1514
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@## main #1514 +/- ##
==========================================
- Coverage 64.69% 64.40% -0.30%
==========================================
Files 3 3 Lines 1997 2003 +6 Branches 687 693 +6 ==========================================
- Hits 1292 1290 -2 - Misses 144 146 +2 - Partials 561 567 +6 ☔ View full report in Codecov by Sentry. |
KevinEady
commented
Jun 8, 2024
| fail-fast: false | ||
| matrix: | ||
| node-version: [ 18.x, 20.x, 21.x, 22.x ] | ||
| api_version: |
There was a problem hiding this comment.
Should we add checks for the standard/experimental to ci-win.yml too?
There was a problem hiding this comment.
Good thought... I pretty much copied Gabriel's CI file. I'll comment on his PR to verify, since mine would end up being overwritten when i rebase to master after his is merged.
mhdawson
commented
Jun 14, 2024
Agreed we should do a release to get out the previous fixe that @gabrielschulhof made and then put this out in a SemVer major. |
674fa28 to
83af80cCompareKevinEady
commented
Jun 15, 2024
Hi team, Using some SFINAE magic, I was able to determine at compile time how to associate the finalizer -- either directly or with This means no changes were needed to any existing tests, and I created a new test in |
There was a problem hiding this comment.
Looks good!
I think the Gc vs. NoGc nomenclature is a bit confusing. Unfortunately, we established this in core. I think maybe we should go with DuringGc and OutsideGc. For env, we'd have DuringGcEnv and Env, since Env is already established, but for the finalizer type names I think we can go with DuringGc and OutsideGc for clarity.
| if (isExperimental) { | ||
| assert.strictEqual(binding.finalizer_order.Test.isNogcFinalizerCalled, true, 'Expected nogc finalizer to be called [before ticking]'); | ||
| assert.strictEqual(binding.finalizer_order.Test.isGcFinalizerCalled, false, 'Expected gc finalizer to not be called [before ticking]'); | ||
| assert.strictEqual(isCallbackCalled, false, 'Expected callback not be called [before ticking]'); |
There was a problem hiding this comment.
| assert.strictEqual(isCallbackCalled,false,'Expected callback not be called [before ticking]'); | |
| assert.strictEqual(isCallbackCalled,false,'Expected callback to not be called [before ticking]'); |
| napi_property_attributes attributes = napi_default); | ||
| static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo); | ||
| virtual void Finalize(Napi::Env env); | ||
| virtual void Finalize(NogcEnv env); |
There was a problem hiding this comment.
| virtualvoidFinalize(NogcEnvenv); | |
| virtualvoidFinalize(Napi::NogcEnvenv); |
gabrielschulhof
commented
Jun 24, 2024
I tested this with const{ makeSync, makeAsync }=require('bindings')('test_sync_fini')constdoAsync=process.argv[2]==='async';(functiontest(iter=0){for(leti=0;i<1000000;i++){constid=`${iter}:${i}`if(doAsync){makeAsync(id)}else{makeSync(id)}}setTimeout(test,0,iter+1)})()Here's a video of the output. Guess which column is async 🙂 Screen.Recording.2024-06-24.at.8.46.57.AM.mov |
gabrielschulhof
commented
Jun 24, 2024
We should rename |
KevinEady
commented
Jun 26, 2024
One could argue that being a Node-API wrapper, the naming in this library should be as consistent with Node-API as possible. The (almost) 1-to-1 mapping helps link up with other documentation (eg. referencing the Node-API docs), or translating between Node-API C code and node-addon-api C++ code. I do agree though, the name
By "finalizer type names" do you mean changing the template <typename Finalizer>
static External New(napi_env env, T* data, Finalizer finalizeCallback);If so, I don't think we should change this name since the finalizer passed can accept either a
Makes sense, esp. considering what I said previously. While on the subject of documentation: we don't have any specific entry for "finalization", as a finalizer callback is always documented on each individual object or function, eg:
I propose we create a new top-level documentation page for finalization describing the above, and can have each use of finalizers in the documentation link to this page. |
| private: | ||
| napi_env _env; | ||
| class NogcEnv { | ||
| protected: |
There was a problem hiding this comment.
Should we make this private and have Env be a friend class? With it being protected, the default finalizers (as well as _env) would be exposed in any user-defined classes that extend NogcEnv.
EDIT: I went with this private-friend approach, making this comment out-dated. Can discuss in meeting.
KevinEady
commented
Jul 5, 2024
I've added some WIP documentation on the top-level finalization page: https://github.com/nodejs/node-addon-api/blob/6591a3609c2b94f22956b72736e06b86586556cf/doc/finalization.md |
KevinEady
commented
Jul 10, 2024
@mhdawson@gabrielschulhof as discussed in the 5 July Node-API meeting, I updated the docs to use the concept of a "basic finalizer" as a special categorization of finalizers, and removing the concept of "[a]synchronous". PTAL: https://github.com/nodejs/node-addon-api/blob/7d7b8211552216657494144d0417bf57b690871e/doc/finalization.md Once we finalize (hah) this verbiage, I will update any associated type names in the headers + tests, and update the other docs that have any finalization features. |
gabrielschulhof
commented
Jul 12, 2024
@KevinEady the doc LGTM 👍 |
(this is still a draft PR, is it ready for review?) |
mhdawson
commented
Jul 12, 2024
doc LGTM with a few suggestions:
NOTE: Optimizations via basic finalizers will only occur if using NAPI_EXPERIMENTAL and the NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT define flag has not been set. Otherwise, the engine will not differentiate between basic and (extended) finalizers. there is never any promise that optimization will take place so I think we can just remove that.
In addition to passing finalizers to Napi::Externals and other Node-API constructs, use Napi::BasicEnv::PostFinalize(Napi::BasicEnv, Finalizer) to schedule a callback to run outside of the garbage collector finalization. can we explain without promising it will run outside of gc collection? Maybe something like "to maximize the likelyhood that the finalization not being tied to garbage collection finalization" ... |
KevinEady
commented
Jul 12, 2024
@legendecas the overall C++ work/implementation is finished, but the PR still needs some more work (markdown docs, test docs, ...)
With this, I was trying to convey that using basic finalizers only changes functionality in experimental mode. I could see someone using basic finalizers without experimental mode, running into #1213 and being a bit confused. Maybe we can use some other verbiage?
What do we think of that?
Well, I took inspiration from the Node-API docs for
Also, when you say:
The API is intended to guarantee the callback does not run inside GC, so saying "maximize the likelihood" is not completely accurate, as it 100% will not run inside GC finalization. Since this API strictly deals with callbacks + GC finalization order, I think it's a good thing to keep. |
In Node API meeting 19 July, we discussed:
Yes, remove this.
The name Additionally, we discussed adding an opt-in flag that requires -- at compilation time -- all finalizers are of the basic type, under the realization that:
I suggest using a define: |
NogcEnvBasicEnvrename NoGcEnv to BasicEnv, AddPostFinalizer to PostFinalizer, NoGc/GcFinalizer to Sync/AsyncFinalizer
- Remove discussions about NAPI-EXPERIMENTAL.
Changes since last approval (22 June)
KevinEady
commented
Aug 6, 2024
The Windows experimental CI passed, eg: test (experimental, 20.x, x64, windows-2019) |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
KevinEady
commented
Aug 19, 2024
Hi @gabrielschulhof , IIRC you mentioned you had an in-progress review. Any movement on that? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
mhdawson
commented
Sep 3, 2024
Looks like all comments have been addressed and CI is green. Landing. |
KevinEady
commented
Sep 3, 2024
Hi @legendecas , This PR was merged into main, but the I think it has to do with permissions? |
Napi::NogcEnvclass, taking the place ofNapi::Envin finalizer callbacks.void Napi::NogcEnv::AddPostFinalizer()and overloads.Closes: #1508
TODO: