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

addons: integrate workers with native addons - #118

Closed
addaleax wants to merge 1 commit into
latestfrom
workers-addons
Closed

addaleax wants to merge 1 commit into
latestfrom
workers-addons

Conversation

@addaleax

Copy link
Copy Markdown
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
Copy Markdown
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 :)

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

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.

Nit: extra space after the type.

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.

Yup, done!

Comment thread src/node.cc

void AddEnvironment(Environment* env) {
if (users_.count(env) > 0) return;
users_.insert(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.

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
Copy Markdown
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 …

Comment thread src/node.cc
void AddEnvironment(Environment* env) {
if (users_.count(env) > 0) return;
users_.insert(env);
if (env->is_main_thread()) return;

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.

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

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.

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
Copy Markdown
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!

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

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

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.

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

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 catch, done!

Comment thread src/node.cc
Local<Object> module = args[0]->ToObject(env->isolate());

CHECK_EQ(modpending, nullptr);
do {

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.

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

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.

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

@aqrln aqrln Nov 3, 2017 •

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.

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

aqrln commented Nov 3, 2017

Copy link
Copy Markdown
Contributor

@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

addaleax commented Nov 3, 2017

Copy link
Copy Markdown
Contributor Author

@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

aqrln commented Nov 3, 2017

Copy link
Copy Markdown
Contributor

@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
Copy Markdown
Contributor Author

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

@aqrln

aqrln commented Nov 16, 2017

Copy link
Copy Markdown
Contributor

@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
Copy Markdown
Contributor Author

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

@aqrln

aqrln commented Nov 16, 2017

Copy link
Copy Markdown
Contributor

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

@addaleax

Copy link
Copy Markdown
Contributor Author

@aqrln Sounds good to me!

Comment thread src/node.cc
DLib& operator=(DLib&& other) = delete;

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

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.

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

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.

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

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

@ghost ghost left a comment

Copy link
Copy Markdown

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

addaleax commented Dec 7, 2017

Copy link
Copy Markdown
Contributor Author

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