Skip to content
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

src: add context-aware helpers and init macro #21318

Closed

Conversation

gabrielschulhof
Copy link
Contributor

Introduces macro NODE_MODULE_INIT() which creates the boilerplate for
a context-aware module which can be loaded multiple times via the
special symbol mechanism.

Also introduces class node::WeakData with which one can weakly
associate a native class instance with a JavaScript object, and
convenience methods node::SetMethodWithData() and
node::SetPrototypeMethodWithData() which pass a native pointer
through to bindings.

Together, these APIs allow one to avoid using global static data in
an addon.

Re: #21291 (comment)

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added the c++ Issues and PRs that require attention from people who are familiar with C++. label Jun 13, 2018
@gabrielschulhof gabrielschulhof force-pushed the node-addon-init branch 2 times, most recently from e292f6d to f25f30b Compare June 13, 2018 18:29
src/node.h Outdated

recv->PrototypeTemplate()->Set(fn_name, t);
}

Copy link
Member

Choose a reason for hiding this comment

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

I wouldn’t be a fan of including this in our public API, unless there’s a reason why we would export it from core

We originally had more core of this sort around (e.g. node_object_wrap.h), but it’s a good idea that this generally moved into Nan territory? I’d suggest PR’ing it there

@@ -98,6 +98,107 @@ the `.node` suffix).
In the `hello.cc` example, then, the initialization function is `Initialize`
and the addon module name is `addon`.

When building your addon with node-gyp, using the macro `NODE_GYP_MODULE_NAME`
Copy link
Contributor

Choose a reason for hiding this comment

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

node-gyp -> `node-gyp` for consistency with other mentions?

invocation of `NODE_MODULE_INIT()`:
* `Local<Object> exports`,
* `Local<Value> module`, and
* `Local<Context> context
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing final backtick and period?

* Constructing an instance of this class in the addon initializer such that
`exports` is passed to the constructor,
* Storing the instance in a `v8::External`, and
* exposing methods to JavaScript via `node::SetMethodWithData()` and via
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the first letter case be unified in this list?

@gabrielschulhof
Copy link
Contributor Author

@addaleax @bnoordhuis I have reduced the scope of the PR to the NODE_MODULE_INIT() macro, documentation pertaining to context-aware modules, and an example illustrating its use in a situation where data is stored per addon instance.

@gabrielschulhof
Copy link
Contributor Author

@vsemozhetbyt I have fixed the issues you mention.

@vsemozhetbyt
Copy link
Contributor

Doc format LGTM.

@gabrielschulhof gabrielschulhof force-pushed the node-addon-init branch 2 times, most recently from 237c4f3 to ac20ee3 Compare June 20, 2018 22:40
@@ -98,6 +98,120 @@ the `.node` suffix).
In the `hello.cc` example, then, the initialization function is `Initialize`
and the addon module name is `addon`.

When building your addon with `node-gyp`, using the macro `NODE_GYP_MODULE_NAME`
Copy link
Member

Choose a reason for hiding this comment

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

nit: "When building addons with..."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, I let that one slip :) Thanks!

@gabrielschulhof
Copy link
Contributor Author

@gabrielschulhof
Copy link
Contributor Author

Another CI before I land: https://ci.nodejs.org/job/node-test-pull-request/15639/

@devsnek
Copy link
Member

devsnek commented Jun 26, 2018

this needs another approval to land

@gabrielschulhof
Copy link
Contributor Author

@devsnek aaah, thank you! Wasn't sure.

@vsemozhetbyt
Copy link
Contributor

It seems our docs state only one approving is needed to land a not fast-track PR.

@gabrielschulhof
Copy link
Contributor Author

@vsemozhetbyt actually, it says it must be two if a Collaborator is the originator of the PR. I checked after @devsnek's reminder: https://github.com/nodejs/node/blob/master/COLLABORATOR_GUIDE.md#code-reviews

@vsemozhetbyt
Copy link
Contributor

vsemozhetbyt commented Jun 27, 2018

Do you refer this sentence?

In the case of pull requests proposed by an existing Collaborator, an additional Collaborator is required for sign-off.

I read it as "One Collaborator is the PR author, another Collaborator is a reviewer".

@gabrielschulhof
Copy link
Contributor Author

gabrielschulhof commented Jun 27, 2018 via email

@vsemozhetbyt
Copy link
Contributor

vsemozhetbyt commented Jun 27, 2018

Let's see how others understand this. It seems we have a bit confusing wording here.

@Trott
Copy link
Member

Trott commented Jun 28, 2018

This does not need a second reviewer, although I would try pinging a relevant team or two before landing, just to get a second one.

@gabrielschulhof
Copy link
Contributor Author

@nodejs/collaborators in the spirit of #21565 (comment), could somebody else please have a look? 🙂

@ryzokuken
Copy link
Contributor

Aww, the dreaded mention.

P.S. I'll take a look :)

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

LGTM

### Context-aware addons

There are environments in which Node.js addons may need to be loaded multiple
times in multiple contexts. The macro `NODE_MODULE_INIT()` will construct an
Copy link
Member

Choose a reason for hiding this comment

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

Can you please articulate what could be those cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mcollina how about the new paragraph I added?

Copy link
Member

Choose a reason for hiding this comment

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

That’s perfect!

Copy link
Contributor

@ryzokuken ryzokuken left a comment

Choose a reason for hiding this comment

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

LGTM, but if I were you, I'd wait for @addaleax's review.

@gabrielschulhof
Copy link
Contributor Author

@addaleax could you please take another look?

Gabriel Schulhof added 3 commits June 30, 2018 20:24
Introduces macro `NODE_MODULE_INIT()` which creates the boilerplate for
a context-aware module which can be loaded multiple times via the
special symbol mechanism.

Additionally, provides an example of using the new macro to construct
an addon which stores per-addon-instance data in a heap-allocated
structure that gets passed to each binding, rather than in a collection
of global static variables.

Re: nodejs#21291 (comment)
@gabrielschulhof
Copy link
Contributor Author

Rebased and added doc for NODE_MODULE_INITIALIZER.

@Trott
Copy link
Member

Trott commented Jul 1, 2018

@gabrielschulhof
Copy link
Contributor Author

@gabrielschulhof
Copy link
Contributor Author

Landed in 602da64.

gabrielschulhof pushed a commit to gabrielschulhof/node that referenced this pull request Jul 3, 2018
Introduces macros `NODE_MODULE_INITIALIZER` which expands to the name
of the special symbol that process.dlopen() will look for to initialize
an addon, and `NODE_MODULE_INIT()` which creates the boilerplate for
a context-aware module which can be loaded multiple times via the
special symbol mechanism.

Additionally, provides an example of using the new macro to construct
an addon which stores per-addon-instance data in a heap-allocated
structure that gets passed to each binding, rather than in a collection
of global static variables.

Re: nodejs#21291 (comment)
PR-URL: nodejs#21318
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
@gabrielschulhof gabrielschulhof deleted the node-addon-init branch July 3, 2018 22:35
@Trott
Copy link
Member

Trott commented Jul 3, 2018

CI was not green. I think we need stronger wording in our docs about not landing stuff when CI is not green. I'll open a PR for that right now.

If you have a mostly-green node-test-pull-request, you're fairly certain the not-green stuff isn't relevant to your changes, and you want to re-run just the things that aren't green, use "Resume Build" on the left menu. It will create a new node-test-pull-request, copy over all the green stuff, and only re-run the red/yellow/grey stuff.

Post-landing CI: https://ci.nodejs.org/job/node-test-pull-request/15717/

EDIT: Can't re-run CI because the branch has been deleted. So in lieu of that, here's a node-daily-master run manually kicked off to re-test this: https://ci.nodejs.org/job/node-daily-master/1203/

@gabrielschulhof
Copy link
Contributor Author

@Trott sorry about that! One job failed on what looked like an infra issue (unable to create a directory). Using "Resume Build" is an awesome option! I didn't know about it.

@Trott
Copy link
Member

Trott commented Jul 3, 2018

@Trott sorry about that! One job failed on what looked like an infra issue (unable to create a directory). Using "Resume Build" is an awesome option! I didn't know about it.

Sorry, didn't mean to pick on you! No need to apologize. You're far from alone. I'm just trying to spread the word about Resume Build. :-D (I didn't know about it until someone else on Build showed it to me...I think it was @refack.)

targos pushed a commit that referenced this pull request Jul 4, 2018
Introduces macros `NODE_MODULE_INITIALIZER` which expands to the name
of the special symbol that process.dlopen() will look for to initialize
an addon, and `NODE_MODULE_INIT()` which creates the boilerplate for
a context-aware module which can be loaded multiple times via the
special symbol mechanism.

Additionally, provides an example of using the new macro to construct
an addon which stores per-addon-instance data in a heap-allocated
structure that gets passed to each binding, rather than in a collection
of global static variables.

Re: #21291 (comment)
PR-URL: #21318
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
@targos targos mentioned this pull request Jul 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants