-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
module: maintain separate cache for native modules #6165
Conversation
A couple of caveats that come to my mind:
Still it seems better than just failing. |
@@ -1422,6 +1441,7 @@ void InitFs(Local<Object> target, | |||
env->SetMethod(target, "readdir", ReadDir); | |||
env->SetMethod(target, "internalModuleReadFile", InternalModuleReadFile); | |||
env->SetMethod(target, "internalModuleStat", InternalModuleStat); | |||
env->SetMethod(target, "internalModuleRealpath", InternalModuleRealpath); |
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: internalModuleRealPath
Tentatively marking this as a semver-major due to the nature of change. |
Not a fan. A lot of complexity for something that can be addressed by a one-liner in the documentation. |
@bnoordhuis it also fixes some other cases of loading the same addon twice |
@vkurchatkin ... could those cases be separated out? That is, separate the fix that addresses the addons being loaded twice from the rest of it? For the cache clearing case, I'm wondering if providing a simple |
@jasnell I'm pretty sure this is that fix. |
@jasnell @Fishrock123 yep, using real path as cache key also solves crash when requiring |
@Fishrock123 ... sorry, I wasn't clear. I meant (a) separating out the commits and (b) rather than having the separate |
This won't really fix existing code, so it will work only for users that know about this problem and change their code to avoid it. This is already possible to implement in userland by filtering out paths with |
yep, good point. I generally agree with @bnoordhuis with regards to the additional complexity of this but I understand the reasoning behind it. I guess I'm +0 on it for now. |
This doesn't really seem all that complex to me. I'm not particularly against it. |
The nature of the module system is such that if we land this change, we're stuck with it forever. If that doesn't convince you: it's a workaround for bad user expectations. That's what documentation is for. |
Users expect things to work, if that's what you mean. It's a good thing that we handle some cases that previously resulted in crash, isn't it? The other option is to deprecate mutating cache altogether. Everything else is a half measure. |
You know what I mean. The OP in #6160 assumed that add-ons could be unloaded by deleting from the cache, but they can't because of technical reasons. If your position is that we hide that detail with a shadow cache, then that's a valid position to take - but it's one I don't agree with. :-) |
I'm +1 on doing something about this but +0 on this change and unfortunately don't have a better idea just now. While I have sympathy for @bnoordhuis' position I don't agree with "The nature of the module system is such that if we land this change, we're stuck with it forever" on this change, there's no reason we couldn't undo it in another semver-major. It also seems that a lot of the complexity of this change comes from introducing One concern with this solution is we'd be hiding the cache from users when there are good reasons to expose that data for native modules just like standard modules. An ideal solution here would be to prevent them from deleting cached data for native modules. Perhaps one way of doing this that wouldn't involve a huge perf hit would be to use an internal cache for native modules and each time it's queried, copy the key/value to |
7da4fd4
to
c7066fb
Compare
c133999
to
83c7a88
Compare
Checklist
Affected core subsystem(s)
module
Description of change
require.cache
is often used to "unload" required modules for testing purposes.This don't quite works for native purposes, because you can't load them twice.
The solution is to maintain independent cache for native modules so we can
create new module instance without invoking
dlopen
.Result of
realpath
is used as cache key to avoid loading same module twiceon case-insensitive file systems.
Fixes: #6160