turbopack: emit assets before duplicate check in emit_assets#93875
turbopack: emit assets before duplicate check in emit_assets#93875sokra wants to merge 2 commits into
Conversation
Reorder emit_assets so the actual emit() runs before check_duplicates(). Under eventual consistency the duplicate check can crash, and we want the asset written to disk regardless.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Failing test suitesCommit: a782c34 | About building and testing Next.js
Expand output● create-next-app default template › should create and run without browser warnings or errors
Expand output● pnpm-workspace-root › should detect root directory from pnpm-workspace.yaml and allow imports from outside app dir ● pnpm-workspace-root › should not have multiple lockfiles warning when pnpm-workspace.yaml is present
Expand output● pnpm-workspace-root › should detect root directory from pnpm-workspace.yaml and allow imports from outside app dir ● pnpm-workspace-root › should not have multiple lockfiles warning when pnpm-workspace.yaml is present Other failing CI jobs |
| @@ -116,8 +116,11 @@ pub async fn emit_assets( | |||
| .resolved_cell() | |||
There was a problem hiding this comment.
this cell is now non-deterministic
at least add a comment, but we could fix it by moving construction into a new task and using as_side_effect (i think)
What?
Reorders
emit_assetsincrates/next-core/src/emit.rsso that the actualemit()/emit_rebase()writes happen beforecheck_duplicates()runs, and parallelizes the per-duplicate diff checks insidecheck_duplicates.Why?
Under eventual consistency, all children might be removed from
emit_assets. This causes allcontent()andemit()tasks being inactive and keeping the stale value (which is potentially an error).On recomputation of
emit_assets()this only make very fewcontent()tasks active, as tasks are still in a slate error state and makeemit_assets()exit early. So it takes N recomputations ofemit_assets()to be up-to-date, where N is the number of duplicate assets. This can slow down builds drastically and did cause build time up to 30min.How?
emit_assets(server-sideemitand client-sideemit_rebase) so the write happens first, thencheck_duplicatesruns as a diagnostic afterwards. A comment is left explaining the ordering requirement.check_duplicatesnow returnsResult<()>instead of returning the picked asset. The caller picksassets.first()directly, sincecheck_duplicatesonly validated equivalence — it didn't choose a different asset.check_duplicatestoiter.map(async |next| { ... }).try_join().await?, running the diff comparisons in parallel.extis computed once before the loop and cloned into each task.