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

Fix a race condition in @babel/core #14843

Conversation

JLHwung
Copy link
Contributor

@JLHwung JLHwung commented Aug 10, 2022

Q                       A
Fixed Issues? Fixes #14806 (comment)
Patch: Bug Fix? Y
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

This PR fixes a race condition in createUncachedDescriptors: After we asynchronously initialize plugins/presets descriptors, we don't check again whether it has been initialized in another task. So we assign different descriptors to config item and the plugins/presets are loaded more than once.

I recommend to review this PR by commits.

This PR also reverts #14806 per Nicolò's comment on that PR.

@JLHwung JLHwung added PR: Bug Fix 🐛 A type of pull request used for our changelog categories pkg: core labels Aug 10, 2022
@babel-bot
Copy link
Collaborator

babel-bot commented Aug 10, 2022

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/52713/

liuxingbaoyu
liuxingbaoyu previously approved these changes Aug 11, 2022
Comment on lines 136 to 142
const _plugins = yield* createPluginDescriptors(
options.plugins || [],
dirname,
alias,
);
// check plugins again to avoid race conditions
plugins ??= _plugins;
Copy link
Member

Choose a reason for hiding this comment

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

Instead of just ignoring the result of the second createPluginDescriptors call, can we avoid calling it twice in the first place? Something like this:

  let pluginsGen;
  return {
    options: optionsWithResolvedBrowserslistConfigFile(options, dirname),
    *plugins() {
      pluginsGen ??= createPluginDescriptors(
        options.plugins || [],
        dirname,
        alias,
      );
      return yield* pluginsGen;
    }
  };

Copy link
Contributor Author

@JLHwung JLHwung Aug 13, 2022

Choose a reason for hiding this comment

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

If we cache the iterator instead, test will fail because the finished iterator always return undefined: https://github.com/JLHwung/babel/runs/7819160996?check_suite_focus=true

Copy link
Member

Choose a reason for hiding this comment

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

I pushed a commit to do the caching, so that now:

  • The first call runs createPluginDescriptors, and after a while returns it
  • The second call waits for the result of the first call, and returns it

Instead of

  • The first call runs createPluginDescriptors, and returns the result of the createPluginDescriptors that finishes first
  • The second call runs createPluginDescriptors, and returns the result of the createPluginDescriptors that finishes first

This avoids resolving the same plugins/presets multiple times, which is a costly operation because it involves the filesystem.

@liuxingbaoyu
Copy link
Member

liuxingbaoyu commented Aug 16, 2022

Unfortunately, this test does not reflect the real problem.
CI still has tens of thousands of lines of logs, even before @nicolo-ribaudo's commit.

https://github.com/babel/babel/runs/7775496327?check_suite_focus=true

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Aug 16, 2022

It's probably because we build Babel using an older version of itself 🤔 This PR still fixes the issue shown in the test, we can potentially wait to revert #14806 until after the new release.

Copy link
Member

@liuxingbaoyu liuxingbaoyu left a comment

Choose a reason for hiding this comment

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

Makes sense! Let's merge it first.

For #14806 I think it's good to keep it that way, only a few of us will see these logs anyway.😄

@nicolo-ribaudo nicolo-ribaudo merged commit c45da3d into babel:main Aug 16, 2022
@nicolo-ribaudo nicolo-ribaudo deleted the fix-create-uncached-descriptors-race-conditions branch August 16, 2022 10:43
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Nov 18, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: core PR: Bug Fix 🐛 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants