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
[Discussion] Requiring Native Modules in the Renderer Process to be NAPI or Context Aware #18397
Comments
|
This is cool. I just encountered such situation that needs multiple native module instances, while it is little sad that it only supports node with V8, not N-API. |
|
Are native modules the only reason for the "new process for every navigation"? The following explanation from @zcbenz seems to suggest that node can't fully tear down its one js environment per process, so a new one can take its place. |
|
@bughit That situation has changed in recent times, as mentioned in the original issue text with the introduction of worker threads node now supports multiple instances of node per-process along with proper teardown support (this is what making your addon context aware supports). We already teardown node environments when the |
|
Would you consider adding an experimental option that would deactivate the "process for every navigation" mode even before you completely drop you process model patches? Assuming that's less work than the full job. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
|
Can the decision to remove affinity be reviewed ? I currently don't see a way to open multiple BrowserWindows quickly enough without affinity. This would impact many developers as discussed here - #16319 |
|
Is there a way to suppress the deprecation warning? I am upgrading to electron 7.x and plan to update my native modules soon, but right now this message floods the log when I run my test suite. (I tried explicitly setting |
I feel what you’re saying but it’s not the problem with ecosystem. Ecosystem gives you an ability to easily update dependencies. It’s up to you to deal with according problems. If you’re not having enough time/desire to resolve that, just don’t update modules, never ever. Additionally to that I’d mention, using
Once an OS developer recommended me to never use this caret symbol for node and setup my config to change the default, - because it introduces all those mentioned problems. He knew something about resilience, about reliability, he was an OS developer, so I listened to his advice. And guess what? I never had this problem again (except in the projects where this practice wasn’t yet applied). So that is what I can recommend to you, and to everybody who faces this problem. You can do this by simply: Or, for yarn: |
|
Yeah, I fix the versions when I need to. That's why I say I'm stuck with an older electron version. However, it is nice to be able to update from time to time for improved security and bug fixes. |
I would be very careful with this advice, it depends on the software whether this is a good idea. Security issues become known in packages you use (directly and indirectly) and from the point they are known publicly, every script kiddy under the sun will start looking for unpatched software. This is an ecosystem problem because in other ecosystems you can update the foundations to stay up-to-date with security fixes without them breaking compatibility. A library like Qt you can do updates for 10 years with no or minimal upkeep while with electron you'll be lucky to go longer than 8 weeks. |
|
Made the tweaks below to get it to run but it still crashes with:
Adding Moment timestamps and Decimals...
Status: Parsing dates and amounts...
TypeError: Cannot read property 'replace' of undefined
at addMomentsAndDecimals (/home/wink/prgs/rust/myrepos/referral-analyzer/analyzeIncome.js:124:53)
at Array.forEach (<anonymous>)
at analyzeIncome (/home/wink/prgs/rust/myrepos/referral-analyzer/analyzeIncome.js:969:34)
at async IpcMainImpl.<anonymous> (/home/wink/prgs/rust/myrepos/referral-analyzer/main.js:74:3)
Status: Hmm... there was some kind of error. Program stopped.
Status: TypeError: Cannot read property 'replace' of undefined
at addMomentsAndDecimals (/home/wink/prgs/rust/myrepos/referral-analyzer/analyzeIncome.js:124:53)
at Array.forEach (<anonymous>)
at analyzeIncome (/home/wink/prgs/rust/myrepos/referral-analyzer/analyzeIncome.js:969:34)
at async IpcMainImpl.<anonymous> (/home/wink/prgs/rust/myrepos/referral-analyzer/main.js:74:3)
README.md
- Add minimal info so I know how to "run" the app
main.js:
- Was getting error:
wink@3900x:~/prgs/rust/myrepos/referral-analyzer (master)
$ electron .
Electron could not be found. No hard resets for you!
Changed the require('electron-reload')(__dirname) which "fixes" that
error. But there is still a warning:
(electron) The default value of app.allowRendererProcessReuse is deprecated, it is currently "false". It will change to be "true" in Electron 9. For more information please check electron/electron#18397
|
same problem with electron >= 16. |
|
Considering the complexity of this thread it's seemingly lacking an ELI5 — is this currently without a workaround? |
|
It is not about complexity is about that many open source node modules haven't switched yet to NAPI and are not Context Aware. So now that Electron removed the So I really wish that Electron left the |
Native modules in Electron
Loading native modules in Electron has always been tricky. It's a pain to rebuild, to link to the right
node.lib/dll, and to ensure yourNODE_MODULE_VERSIONis correct. And there's another problem behind the scenes that most users have never had to deal with: Node doesn't let you load multiple instances of a native module in the same process, even in different v8 contexts. Imagine this scenario:We address this in Electron by patching Chromium to create a new process for every navigation. This mostly works but still has a few edge cases (e.g. #4025, #12045, #17576) and a few side effects:
window.openandwindow.openeras we force child windows into separate processes sometimes.We've always thought "wouldn't it be cool if we could change this". Now, with Node 12's Worker Threads, we see a way to do that.
Worker Threads
Node ran into the same issue when they added worker threads: native modules could not be loaded in multiple workers. Node solved this by introducing the concept of "Context Aware" native modules. This is how native modules tell Node that they are safe to be loaded in multiple
v8::Contexts. Nan has a handy helper (NAN_MODULE_WORKER_ENABLED) for doing this.Context Aware modules and NAPI modules can be instantated multiple times in Node even without our patched process model. As they become more common, our patches will bring less benefit and be more redundant.
What does this mean for Electron?
Right now, nothing. However, at some point in the future -- probably in a few major versions -- we intend to remove our process model patches. At that point, any native Node modules loaded in the renderer process must be either NAPI or Context Aware.
This won't happen tomorrow. It probably won't happen this year. But it will happen, so if you're using or maintaining a native module, you should start looking at the work to mark it as Context Aware. For lots of modules it's as easy as replacing
NODE_MODULEwithNAN_MODULE_WORKER_ENABLED. For modules that require cleanup, it can be more involved.You may be wondering why we're changing something that (mostly) works? The main reasons are:
What does this look like for Native Module X?
The amount of work to become "Context Aware" will be different for every module. For native modules that act as proxies for native getters and setters -- i.e. they just expose JS apis to acccess native APIs -- it's normally as easy as adding a
NAN_MODULE_WORKER_ENABLEDdeclaration. You can find an example of that in this pull request.Some modules will need to do cleanup when the context is destroyed to ensure the module doesn't leaking memory or to cause crashes. You can add hooks to clean up after yourself with
node::AddEnvironmentCleanupHookA minimal example of this can be found in this pull request.Timeline
app.allowRendererProcessReuseoption in Electron 6app.allowRendererProcessReuseto switchapp.allowRendererProcessReusetotruein Electron 9app.allowRendererProcessReusein Electron 10app.allowRendererProcessReusein Electron 14The text was updated successfully, but these errors were encountered: