-
Notifications
You must be signed in to change notification settings - Fork 97
addons: integrate workers with native addons #118
Conversation
@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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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;
.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
cb9131a
to
2b21717
Compare
src/node.cc
Outdated
bool is_opened = dlib->Open(); | ||
|
||
if (is_opened) { | ||
if (handle_to_dlib.count(dlib->handle_) > 0) { |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch, done!
2b21717
to
14c2355
Compare
|
||
CHECK_EQ(modpending, nullptr); | ||
do { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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!
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. |
@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 |
@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.
@aqrln Okay, getting back on all of this … maybe schedule a call for the weekend, if that works with you? |
14c2355
to
66f85d9
Compare
@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. |
@aqrln I think Monday evening (>= 18:00 CET/17:00 UTC/19:00 EET) should be fine :) |
@addaleax great, thanks. How about 20:00 CET/19:00 UTC/21:00 EET? |
@aqrln Sounds good to me! |
DLib& operator=(DLib&& other) = delete; | ||
|
||
void AddEnvironment(Environment* env) { | ||
if (users_.count(env) > 0) return; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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`)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this change?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this 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!
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>
Landed in fbd7c6e |
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
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), orvcbuild test
(Windows) passesAffected core subsystem(s)
workers/addons