Skip to content
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

esm: remove proxy for builtin exports #29737

Closed
wants to merge 5 commits into from

Conversation

bmeck
Copy link
Member

@bmeck bmeck commented Sep 27, 2019

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

This removes the proxy from builtin modules used to sync named exports. Instead, a manual call to require('module').syncESMExports() will sync all the builtin exports except default properties. The semantics need documentation updated, but wanted to open this to make sure the semantics are the expected ones and make sure test changes match expectations.

CC: @nodejs/modules

@bmeck bmeck added wip Issues and PRs that are still a work in progress. esm Issues and PRs related to the ECMAScript Modules implementation. modules-agenda Issues and PRs to discuss during the meetings of the Modules team. labels Sep 27, 2019
Copy link
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

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

Thanks so much for getting to this one. As discussed in the last meeting this seems a great way to avoid any potential perf issues from the proxies.

We should probably include a documentation note on the syncESMExports API in module.md.

lib/internal/modules/esm/translators.js Outdated Show resolved Hide resolved
lib/internal/modules/cjs/loader.js Outdated Show resolved Hide resolved
Copy link
Contributor

@jkrems jkrems left a comment

Choose a reason for hiding this comment

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

I think this is great! Thanks for working on it. It looks pretty close to something we can ship as-is, one minor bikeshed on "sync all" method name aside.


this.exports = new Proxy(this.exports, handler);
// const handler = {
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume this code will be removed before shipping?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, cleanup and docs are pending semantic reviews

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good, I'll leave this thread as a reminder.

Copy link
Member Author

Choose a reason for hiding this comment

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

@jkrems should be good for another review

lib/internal/modules/esm/translators.js Outdated Show resolved Hide resolved
lib/internal/modules/cjs/loader.js Outdated Show resolved Hide resolved
Copy link
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

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

LGTM

@ljharb
Copy link
Member

ljharb commented Sep 27, 2019

Does this mean that live bindings no longer work? Or is this just an alternate approach with the same runtime semantics but improved performance?

@jkrems
Copy link
Contributor

jkrems commented Sep 27, 2019

@ljharb It means live bindings are no longer implicit. If an instrumentation library wants to mutate http.request and have it show up in import { request } from 'http', it now has to call .syncESMExports afterwards. It felt like a valid trade-off between advanced users wanting to mess with internals and performance.

@ljharb
Copy link
Member

ljharb commented Sep 27, 2019

Gotcha, thanks for clarifying.

@ljharb
Copy link
Member

ljharb commented Sep 27, 2019

Instead of this, or a Proxy, have setters been considered?

@bmeck
Copy link
Member Author

bmeck commented Sep 27, 2019

@ljharb setters would suffer same perf problem which was the issue in #29426 also it wouldn't cover cases like deletes or defineProperty

Copy link
Member

@devsnek devsnek left a comment

Choose a reason for hiding this comment

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

👀

@jdalton
Copy link
Member

jdalton commented Sep 27, 2019

Is there a performance problem in the wild for reference?

@bmeck
Copy link
Member Author

bmeck commented Sep 27, 2019

@jdalton this partly based upon #29426 , which saw slowdown on process.nextTick, if modules are enabled even if they are not used; it shows up in most benchmarks that spin the event loop.

@jdalton
Copy link
Member

jdalton commented Sep 27, 2019

I'd be curious to know what the slowdown is (how dramatic in %) and if it's something we should direct to V8. They've been doing a lot of work on optimizing Proxies.

I think being explicit for core is fine. Maybe not so user-friendly but user-land is there in most cases to smooth things over as needed.

@mcollina
Copy link
Member

There is multiple evidence that any slowdown in process.nextTick will slow down http servers for example. Node 12.10.0 had a 30% regression in http throughput because of changes in process.nextTick. Adding any intermediate layer there is not possible.

Note that this applies to process.nextTick and some other few hot paths in Node core. As a result, we cannot have the global process object be a Proxy.

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

LGTM

@jdalton
Copy link
Member

jdalton commented Sep 27, 2019

Is this design premature optimization then since the nextTick scenario is one of a small group of super hot areas?

@mcollina
Copy link
Member

@jdalton my point of view is expressed in #29426 (comment).

@nodejs-github-bot
Copy link
Collaborator

Copy link
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

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

I notice that syncExports doesn't re-sync the default export of the module.exports value is overridden somehow. Not sure if this is possible, but it could be worth ensuring this for definite?

@guybedford
Copy link
Contributor

Just had a brief chat with @bmeck about this and we're both happy with the state of the PR to merge. Removing the WIP flag.

@guybedford guybedford removed modules-agenda Issues and PRs to discuss during the meetings of the Modules team. wip Issues and PRs that are still a work in progress. labels Oct 4, 2019
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

Trott
Trott previously requested changes Oct 5, 2019
Copy link
Member

@Trott Trott left a comment

Choose a reason for hiding this comment

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

tools/doc/README.md should not change. The REPLACEME example in that doc is correct.

tools/doc/README.md Outdated Show resolved Hide resolved
@Trott
Copy link
Member

Trott commented Oct 5, 2019

The CI output indicates that the REPLACEME problem is in modules.md so it is almost certainly introduced in this PR.

doc/api/modules.md Outdated Show resolved Hide resolved
@nodejs-github-bot
Copy link
Collaborator

@guybedford
Copy link
Contributor

@Trott we should be ready to land here finally.

@guybedford
Copy link
Contributor

Windows CI failure seems unrelated.

@Trott Trott dismissed their stale review October 5, 2019 23:48

requested change made

@nodejs-github-bot
Copy link
Collaborator

@Trott
Copy link
Member

Trott commented Oct 5, 2019

Windows CI failure seems unrelated.

When you're looking at a node-test-pull-request result, the "Resume Build" option in the left nav will create a new job that retains all the green results and only re-runs the yellow and green results. Useful for this situation! (And not to be confused with "Rebuild" which will re-run everything.) I just used it (and the bot posted the link right above).

guybedford pushed a commit that referenced this pull request Oct 6, 2019
PR-URL: #29737
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
@guybedford
Copy link
Contributor

@Trott thanks for the suggestion and quick update... will definitely use that one next time.

Landed in 0b495a8.

@guybedford guybedford closed this Oct 6, 2019
@guybedford
Copy link
Contributor

Merging this at the same time as the source maps PR it seems we might have an interaction causing a failure. Looking into a fix PR now, but if I can't get something soon will post a revert.

@guybedford
Copy link
Contributor

So far haven't been able to replicate locally. #29846 is passing against the same master, so it may just be a Travis thing... let's see how the other commits on master go too.

@Trott
Copy link
Member

Trott commented Oct 6, 2019

Here's a CI job I just kicked off against master: https://ci.nodejs.org/job/node-daily-master/1700/

@Trott
Copy link
Member

Trott commented Oct 6, 2019

Here's a CI job I just kicked off against master: https://ci.nodejs.org/job/node-daily-master/1700/

@guybedford That CI job is looking very good. I think you're in the clear.

@guybedford
Copy link
Contributor

guybedford commented Oct 6, 2019 via email

BridgeAR pushed a commit that referenced this pull request Oct 9, 2019
PR-URL: #29737
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
@BridgeAR BridgeAR mentioned this pull request Oct 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
esm Issues and PRs related to the ECMAScript Modules implementation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet