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 concurrent bug due to async execution #2404

Merged
merged 1 commit into from Jul 24, 2022
Merged

Fix a concurrent bug due to async execution #2404

merged 1 commit into from Jul 24, 2022

Conversation

shrinktofit
Copy link
Contributor

@shrinktofit shrinktofit commented Jul 21, 2022

Let me illustrate this BUG.

Here's 3 modules:

// main
export { stamp } from './dep.js';

// dep
import './async-dep.js';
export const stamp = Date.now();

// async-dep
await Promise.resolve();

And the top level execution flow:

const thread1 = import('main'); // #1
const thread2 = import('dep'); // #2
await thread1; // #3
await thread2; // #4

For module dep:

At the end of line #1, load.E was created. But load.e kept non-nil, since dep has async dependencies - the load.e only reset when load.E resolved.

Now enter line #2, because !!load.e, another load.E would be created.

Starting from line #3, the two load.E raced - both call and reset load.e.

@github-actions
Copy link

github-actions bot commented Jul 21, 2022

File size impact

Merging concurrent into main will not impact files in any group.

browser (0/2)

No impact on files in browser group.

node (0/1)

No impact on files in node group.

extras (0/8)

No impact on files in extras group.

Generated by file size impact during size-impact#2726803254

@shrinktofit
Copy link
Contributor Author

@guybedford I don't know why CI failed, network problem?

@guybedford
Copy link
Member

@shrinktofit I was able to update the CI in #2407 so we're no longer on Travis.

This PR feels something closer to the first option I offered before, in us iterating on cases as we go while accepting that the solution is still not yet comprehensive. I'm totally fine with that and trust your judgement of the problem space.

I'm going to merge this and will aim to release in the next couple of days.

If you are interested in some more advanced test cases, it get's pretty wild in https://github.com/evanw/tla-fuzzer.

@Fu-Shengsheng
Copy link

Let me illustrate this BUG.

Here's 3 modules:

// main
export { stamp } from './dep.js';

// dep
import './async-dep.js';
export const stamp = Date.now();

// async-dep
await Promise.resolve();

And the top level execution flow:

const thread1 = import('main'); // #1
const thread2 = import('dep'); // #2
await thread1; // #3
await thread2; // #4

For module dep:

At the end of line #1, load.E was created. But load.e kept non-nil, since dep has async dependencies - the load.e only reset when load.E resolved.

Now enter line #2, because !!load.e, another load.E would be created.

Starting from line #3, the two load.E raced - both call and reset load.e.

The same problem.
When I found it and want issue, it fixed lol.
Anyway, thanks a lot!

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