Skip to content

feat: add support for nogc types via BasicEnv #1514

Merged
mhdawson merged 19 commits into
nodejs:mainfrom
KevinEady:add-nogc-types
Sep 3, 2024
Merged

feat: add support for nogc types via BasicEnv #1514
mhdawson merged 19 commits into
nodejs:mainfrom
KevinEady:add-nogc-types

Conversation

@KevinEady
Copy link
Copy Markdown
Contributor

@KevinEady KevinEady commented Jun 6, 2024

  • Introduce Napi::NogcEnv class, taking the place of Napi::Env in finalizer callbacks.
  • Introduce void Napi::NogcEnv::AddPostFinalizer() and overloads.
  • Modify tests to support above changes

Closes: #1508

TODO:

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jun 6, 2024

Codecov Report

Attention: Patch coverage is 69.38776% with 15 lines in your changes missing coverage. Please review.

Project coverage is 64.40%. Comparing base (12ffe91) to head (195ec28).
Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
napi-inl.h 70.83% 2 Missing and 12 partials ⚠️
napi.h 0.00% 0 Missing and 1 partial ⚠️
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.
📢 Have feedback on the report? Share it here.

@KevinEady
Copy link
Copy Markdown
Contributor Author

@vmoroz your comment on removing const ref on std::nullptr_t has been addressed, and @mhdawson your comment on reference deletion has been addressed, both in 2a689b6

Comment thread .github/workflows/ci.yml
fail-fast: false
matrix:
node-version: [ 18.x, 20.x, 21.x, 22.x ]
api_version:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add checks for the standard/experimental to ci-win.yml too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Member

Agreed we should do a release to get out the previous fixe that @gabrielschulhof made and then put this out in a SemVer major.

@KevinEady KevinEady force-pushed the add-nogc-types branch 4 times, most recently from 674fa28 to 83af80c Compare June 15, 2024 20:57
@KevinEady
Copy link
Copy Markdown
Contributor Author

Hi team,

Using some SFINAE magic, I was able to determine at compile time how to associate the finalizer -- either directly or with node_api_post_finalizer. This would address #1367 as implemented.

This means no changes were needed to any existing tests, and I created a new test in finalizer_order to ensure finalizers are being called correctly.

PTAL! @gabrielschulhof @vmoroz @legendecas @mhdawson

Copy link
Copy Markdown
Contributor

@gabrielschulhof gabrielschulhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread test/finalizer_order.js Outdated
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]');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert.strictEqual(isCallbackCalled, false, 'Expected callback not be called [before ticking]');
assert.strictEqual(isCallbackCalled, false, 'Expected callback to not be called [before ticking]');

Comment thread napi.h Outdated
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);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
virtual void Finalize(NogcEnv env);
virtual void Finalize(Napi::NogcEnv env);

@gabrielschulhof
Copy link
Copy Markdown
Contributor

I tested this with Napi::External and it works great!

const { makeSync, makeAsync } = require('bindings')('test_sync_fini')

const doAsync = process.argv[2] === 'async'

;(function test(iter = 0) {
  for (let i = 0; i < 1000000; i++) {
    const id = `${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