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

module: cache synchronous module jobs before linking #52868

Closed
wants to merge 3 commits into from

Conversation

joyeecheung
Copy link
Member

test: add common.expectRequiredModule()

To minimize changes if/when we change the layout of the
result returned by require(esm).

module: cache synchronous module jobs before linking

So that if there are circular dependencies in the synchronous
module graph, they could be resolved using the cached jobs.
In case linking fails and the error gets caught, reset the
cache right after linking. If it succeeds, the caller will
cache it again. Otherwise the error bubbles up to users,
and since we unset the cache for the unlinkable module
the next attempt would still fail.

Fixes: #52864

To minimize changes if/when we change the layout of the
result returned by require(esm).
So that if there are circular dependencies in the synchronous
module graph, they could be resolved using the cached jobs.
In case linking fails and the error gets caught, reset the
cache right after linking. If it succeeds, the caller will
cache it again. Otherwise the error bubbles up to users,
and since we unset the cache for the unlinkable module
the next attempt would still fail.
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/loaders

@nodejs-github-bot nodejs-github-bot added esm Issues and PRs related to the ECMAScript Modules implementation. needs-ci PRs that need a full CI run. labels May 7, 2024
@nodejs-github-bot
Copy link
Collaborator

lib/internal/modules/esm/module_job.js Show resolved Hide resolved
test/common/index.js Show resolved Hide resolved
test/fixtures/es-modules/cjs-esm-esm-cycle/a.mjs Outdated Show resolved Hide resolved
@nodejs-github-bot
Copy link
Collaborator

Co-authored-by: Yagiz Nizipli <yagiz@nizipli.com>
@nodejs-github-bot
Copy link
Collaborator

@aduh95 aduh95 added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. labels May 8, 2024
assert(this.module instanceof ModuleWrap);
// Store itself into the cache first before linking in case there are circular
// references in the linking.
loader.loadCache.set(url, importAttributes.type, this);
Copy link
Member

Choose a reason for hiding this comment

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

Setting in cache at

job = new ModuleJobSync(this, url, importAttributes, wrap, isMain, inspectBrk);
this.loadCache.set(url, importAttributes.type, job);
would be redundant but I think it could be a follow up work.

Copy link
Member Author

Choose a reason for hiding this comment

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

That was what I did initially but it would cache modules that failed to link and if that’s caught, subsequent attempts would not fail as expected - which is why I added comments explaining why it’s reset in the finally block (doing it inside the linking phase prevents a rethrow in the caller which looks less nice)

Copy link
Member

@legendecas legendecas May 8, 2024

Choose a reason for hiding this comment

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

Hmmm, maybe we could transform the try-finally into a try-catch-rethrow and only delete in catch? In this way we don't need to set cache again in the caller.

Copy link
Member Author

Choose a reason for hiding this comment

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

The rethrow was exactly what I am trying to prevent - setting the cache again is fine as the overhead is trivial but having to rethrow in all callers of this makes the code harder to read IMO. It also makes all the source lines of the errors less readable, which shows in the stderr when they are not caught.

@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label May 9, 2024
@nodejs-github-bot
Copy link
Collaborator

Landed in 1291d3d...2863c54

nodejs-github-bot pushed a commit that referenced this pull request May 9, 2024
To minimize changes if/when we change the layout of the
result returned by require(esm).

PR-URL: #52868
Fixes: #52864
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
nodejs-github-bot pushed a commit that referenced this pull request May 9, 2024
So that if there are circular dependencies in the synchronous
module graph, they could be resolved using the cached jobs.
In case linking fails and the error gets caught, reset the
cache right after linking. If it succeeds, the caller will
cache it again. Otherwise the error bubbles up to users,
and since we unset the cache for the unlinkable module
the next attempt would still fail.

PR-URL: #52868
Fixes: #52864
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
targos pushed a commit that referenced this pull request May 11, 2024
To minimize changes if/when we change the layout of the
result returned by require(esm).

PR-URL: #52868
Fixes: #52864
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
targos pushed a commit that referenced this pull request May 11, 2024
So that if there are circular dependencies in the synchronous
module graph, they could be resolved using the cached jobs.
In case linking fails and the error gets caught, reset the
cache right after linking. If it succeeds, the caller will
cache it again. Otherwise the error bubbles up to users,
and since we unset the cache for the unlinkable module
the next attempt would still fail.

PR-URL: #52868
Fixes: #52864
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. esm Issues and PRs related to the ECMAScript Modules implementation. needs-ci PRs that need a full CI run.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Experimental require of circular ESM graph stack overflow
7 participants