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

[node-modules] Support reducing trees requiring multiple hoisting passes to a terminal result #2394

Merged
merged 17 commits into from Feb 5, 2021

Conversation

larixer
Copy link
Member

@larixer larixer commented Jan 20, 2021

What's the problem this PR addresses?

Fixes issue:
babel/babel#12583 (comment)
The issue happens because the dependency graph was not fully hoisted, which resulted in an unlucky situation when the place was temporary occupied in a single workspace by conflicting versions of the same dependency.

How did you fix it?

The simplified example of a dependency graph requiring multiple hoisting passes is below:

. -> A -> D@X -> F@X -> E@X -> B@Y -> C@Z
                            -> C@X
                     -> C@Z
              -> C@X      
  -> B@X
  -> C@Z
  -> D@Y
  -> E@Y
  -> F@Y

We try to hoist everything we can to the . node first, we cannot hoist anything
Then we try to hoist everything we can to A (C@Z has a priority, because its more popular), we have

. -> A -> D@X -> C@X
       -> F@X
       -> E@X -> C@X
       -> B@Y 
       -> C@Z
  -> B@X
  -> C@Z
  -> D@Y
  -> E@Y
  -> F@Y

And now we can hoist C@Z from A, but we need another pass to do it, because we need to try to hoist to the root again, and the final result will be:

. -> A -> D@X -> C@X
       -> F@X
       -> E@X -> C@X
       -> B@Y 
  -> B@X
  -> C@Z
  -> D@Y
  -> E@Y
  -> F@Y

I have fixed the issue by adding support of detecting the case when multiple rounds of hoisting are needed. The algorithm stops when detection yields no results, thus the minimum number of required rounds are performed. I have also added to a self-check the validation whether result is actually terminal, by doing another hoisting round and checking whether any hoisting was performed during this additional round.

Checklist

  • I have set the packages that need to be released for my changes to be effective.
  • I will check that all automated PR checks pass before the PR gets reviewed.

@nicolo-ribaudo
Copy link
Contributor

For this repo 3 passes are needed, on the 1st and 2nd pass the hoisting layout changes and on 3rd pass nothing is changed, but it is still needed for algorithm to understand that we have a terminal result.
The downside of this approach is that it is obviously slower, in master hoisting takes 380ms for me, and multi-pass hoisting takes 1.28s. I'm still looking into ways to optimise multi-pass hoisting speed.

(babel/babel#12583 (comment) by @larixer)

Maybe yarn could do a single pass by default, and try again with multiple if there is a linking error?

@larixer
Copy link
Member Author

larixer commented Jan 27, 2021

@nicolo-ribaudo

Maybe yarn could do a single pass by default, and try again with multiple if there is a linking error?

Yeah, I'm still investigating why these multiple passes are really needed, maybe all these multiple passes can be really done in a single pass....

@larixer larixer changed the title [node-modules] Ongoing work to fix issue with NM linker spotted in Babel repo [node-modules] Support reducing trees requiring multiple hoisting passes to a terminal result Jan 28, 2021
@larixer larixer marked this pull request as ready for review January 28, 2021 11:20
@larixer larixer marked this pull request as draft January 28, 2021 11:23
@larixer larixer marked this pull request as ready for review February 1, 2021 15:51
@larixer larixer requested a review from arcanis February 1, 2021 15:51
@arcanis arcanis merged commit fbbb7be into master Feb 5, 2021
@arcanis arcanis deleted the larixer/nm-babel-issue branch February 5, 2021 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants