Skip to content

[turbopack] Enforce root attribute for strongly consistent reads and collectibles#93114

Open
sokra wants to merge 2 commits intocanaryfrom
sokra/disallow-root-upgrade
Open

[turbopack] Enforce root attribute for strongly consistent reads and collectibles#93114
sokra wants to merge 2 commits intocanaryfrom
sokra/disallow-root-upgrade

Conversation

@sokra
Copy link
Copy Markdown
Member

@sokra sokra commented Apr 22, 2026

What?

Replaces the silent "make root node" promotion in the turbo-tasks backend with a panic that enforces tasks to already have the root attribute before performing strongly consistent reads, reading task collectibles, or removing collectibles.

Why?

Previously, the backend would silently promote any non-root task to a root node (aggregation number u32::MAX) when these operations were requested. This masked incorrect task configuration — tasks that needed root-level aggregation weren't explicitly declared as such, making it harder to reason about the aggregation graph and hiding potential performance issues from implicit promotions.

How?

Backend enforcement (3 locations):

  • Strongly consistent read (backend/mod.rs): Checks NativeFunction.is_root on the target task. If it's a persistent task without root, panics with both the target and reader task descriptions.
  • Read task collectibles (backend/mod.rs): Same check when reading collectibles from a task.
  • Remove collectibles (operation/update_collectible.rs): Same check when removing collectibles (count < 0).

All three locations drop the task guard before panicking to avoid deadlocking with debug_get_task_description.

Macro support for root on methods:

  • value_impl_macro.rs: Now reads the root attribute from #[turbo_tasks::function(root)] on inherent impl and trait impl methods (previously hardcoded to false).
  • value_trait_macro.rs: Same for trait default methods.

root attribute additions:

  • All #[turbo_tasks::function(operation)] in test files, benchmarks, and fuzz code
  • Production operations in crates/next-api/ that are read with strong consistency
  • Regular functions and methods in tests that use .strongly_consistent()
  • Trait methods in value_impl and value_trait blocks used with strong consistency

New test:

  • non_root_task_panic.rs: Verifies the panic fires when attempting a strongly consistent read on a non-root operation task. Captures the panic from the worker thread via a panic hook since the panic propagates as a channel error to the test thread.

…d collectibles

Replace the silent "make root node" promotion with a panic when trying to
read a non-root task strongly consistent, read task collectibles, or remove
collectibles. Tasks must now be explicitly marked with the `root` attribute
(e.g. `#[turbo_tasks::function(root)]`) to be eligible for these operations.

- Replace 3 "make root node" loops in the backend with `NativeFunction.is_root`
  checks that panic with descriptive messages including both task descriptions
- Support `root` attribute on `#[turbo_tasks::value_impl]` methods and
  `#[turbo_tasks::value_trait]` default methods
- Add `root` to all existing operation functions, regular functions, and methods
  that are read with strong consistency
- Add test verifying the panic fires for non-root tasks
@sokra sokra requested a review from lukesandberg April 22, 2026 01:40
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 22, 2026

Merging this PR will degrade performance by 3.31%

❌ 1 regressed benchmark
✅ 7 untouched benchmarks
⏩ 12 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation react-dom-client.development.js[full] 392.6 ms 406.1 ms -3.31%

Comparing sokra/disallow-root-upgrade (d974c14) with canary (2293d65)

Open in CodSpeed

Footnotes

  1. 12 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Comment thread turbopack/crates/turbo-tasks-macros/src/value_trait_macro.rs
…ait/impl matching

- Add `root` to ~50 operations across napi bindings, next-api, turbopack-core,
  turbopack-dev-server, turbopack-cli, and tests that are read with strong
  consistency or have collectibles taken (`take_effects`,
  `strongly_consistent_catch_collectables`). This unblocks the production build
  panic on `has_deferred_entrypoints_operation` plus the cargo unit/bench fan-out
  (fetch tests, read_glob tests, module_graph tests, tracing tests, etc).
- Enforce `root` attribute matching between `#[turbo_tasks::value_trait]`
  methods and their `#[turbo_tasks::value_impl]` implementations: store
  `is_root` on `TraitMethod` and panic at lazy-init in
  `register_all_trait_methods` if a trait method's `is_root` differs from any
  impl method's `is_root`.
- Removed `root` from `AssetHashesManifestAsset::Asset::content` impl
  (`Asset::content` trait method does not declare `root`).
@lukesandberg lukesandberg marked this pull request as ready for review April 22, 2026 18:52
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.

2 participants