Skip to content
This repository has been archived by the owner on Aug 31, 2018. It is now read-only.

addons: integrate workers with native addons #118

Closed
wants to merge 1 commit into from

Conversation

addaleax
Copy link
Contributor

Native addons need to use flags to indicate that they are capable of being loaded by worker threads.

Native addons are unloaded if all Environments referring to it have been cleaned up, except if it also loaded by the main Environment.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

workers/addons

@addaleax
Copy link
Contributor Author

@ayojs/core I realize this is quite a bit trickier to go through – happy to have a chat about this or something like that if you like :)

src/node.cc Outdated
Environment* env;
};
env->AddCleanupHook([](void* arg) {
Mutex::ScopedLock lock(dlib_mutex);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: extra space after the type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, done!


void AddEnvironment(Environment* env) {
if (users_.count(env) > 0) return;
users_.insert(env);
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this won't hurt readability, but these two lines can be merged into something like if (!users_.insert(env).second) return;.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm yeah, I think the current way is a bit more readable …

void AddEnvironment(Environment* env) {
if (users_.count(env) > 0) return;
users_.insert(env);
if (env->is_main_thread()) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

Also, does the order of these checks matter, and if yes, shouldn't this one be the first one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it matters, because non-main environments check whether the set is empty once they’re being torn down. The idea is that we preserve the current behaviour; if an addon is loaded by the main thread, it is never unloaded.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, thanks for the explanation!

src/node.cc Outdated
bool is_opened = dlib->Open();

if (is_opened) {
if (handle_to_dlib.count(dlib->handle_) > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: if (is_opened && handle_to_dlib.count(dlib->handle_) > 0)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch, done!


CHECK_EQ(modpending, nullptr);
do {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any particular reason to use the do { ... } while (false); pattern instead of a plain { ... } scope here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, the fact that you can break; out of it if you discover that you don’t want to do most of the work here. The alternative would be having quite a sizeable block of code with 2 levels of extra indentation, which would also work

Copy link
Contributor

@aqrln aqrln Nov 3, 2017

Choose a reason for hiding this comment

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

Oh, right. I just noticed the loop when I had opened the PR again, without really looking into its body this time, so I didn't notice the break statements, heh. Thanks for clarifying!

@aqrln
Copy link
Contributor

aqrln commented Nov 3, 2017

@addaleax

I realize this is quite a bit trickier to go through – happy to have a chat about this or something like that if you like :)

I think that might be helpful. I mean, currently I'm just reviewing the code itself, but I don't think I'm really qualified to review the logic that happens here.

@addaleax
Copy link
Contributor Author

addaleax commented Nov 3, 2017

@aqrln The only issue I see is that I’ll be at NodeConf EU for basically all of the next 7 days, so setting up a time for a hangout or so would probably be a bit hard. I guess there’s no rush for this to land tho

@aqrln
Copy link
Contributor

aqrln commented Nov 3, 2017

@addaleax okay, whichever time works for you, especially if the PR can wait for a bit :)

Native addons need to use flags to indicate that they are capable
of being loaded by worker threads.

Native addons are unloaded if all Environments referring to it
have been cleaned up, except if it also loaded by the main Environment.
@addaleax
Copy link
Contributor Author

@aqrln Okay, getting back on all of this … maybe schedule a call for the weekend, if that works with you?

@aqrln
Copy link
Contributor

aqrln commented Nov 16, 2017

@addaleax Monday or Tuesday evening would be ideal, but if you prefer the weekend, I think I can find some time after 18:00 EET / 17:00 CET on Sunday.

@addaleax
Copy link
Contributor Author

@aqrln I think Monday evening (>= 18:00 CET/17:00 UTC/19:00 EET) should be fine :)

@aqrln
Copy link
Contributor

aqrln commented Nov 16, 2017

@addaleax great, thanks. How about 20:00 CET/19:00 UTC/21:00 EET?

@addaleax
Copy link
Contributor Author

@aqrln Sounds good to me!

DLib& operator=(DLib&& other) = delete;

void AddEnvironment(Environment* env) {
if (users_.count(env) > 0) return;
Copy link
Member

Choose a reason for hiding this comment

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

Would access to users_ need to be protected by a mutex?

Copy link
Contributor

Choose a reason for hiding this comment

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

It is kinda protected by dlib_mutex, because this method is only called from DLOpen(), but it would be nice to actually restrict access to the method so that it couldn't be called from another place.

// process.dlopen() a require() call fails.
const re = /^Error: Module did not self-register\.$/;
assert.throws(() => require(`./build/${common.buildType}/binding`), re);
assert.doesNotThrow(() => require(`./build/${common.buildType}/binding`));
Copy link
Member

Choose a reason for hiding this comment

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

Why did this change?

Copy link

Choose a reason for hiding this comment

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

i'm assuming because DLOpen() doesn't throw on missing self-registration anymore, instead it just abandons

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@TimothyGu It changed because re-dlopen()-ing a module will just give you the module again, like what you’d expect require() to do

Copy link

@ghost ghost 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 to me!

addaleax added a commit that referenced this pull request Dec 7, 2017
Native addons need to use flags to indicate that they are capable
of being loaded by worker threads.

Native addons are unloaded if all Environments referring to it
have been cleaned up, except if it also loaded by the main Environment.

PR-URL: #118
Reviewed-By: Alexey Orlenko <eaglexrlnk@gmail.com>
Reviewed-By: Olivia Hugger <olivia@fastmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
@addaleax
Copy link
Contributor Author

addaleax commented Dec 7, 2017

Landed in fbd7c6e

@addaleax addaleax closed this Dec 7, 2017
@addaleax addaleax deleted the workers-addons branch December 7, 2017 15:52
addaleax added a commit to addaleax/node that referenced this pull request May 18, 2018
Native addons need to use flags to indicate that they are capable
of being loaded by worker threads.

Native addons are unloaded if all Environments referring to it
have been cleaned up, except if it also loaded by the main Environment.

Thanks go to Alexey Orlenko, Olivia Hugger and Stephen Belanger
for reviewing the original version of this change.

Refs: ayojs/ayo#118
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants