Skip to content

turbo-tasks-backend: skip dirtying removed cell dependents - #100460

Draft
sokra wants to merge 1 commit into
canaryfrom
fleet/update-cell-skip-removed-dependents
Draft

sokra wants to merge 1 commit into
canaryfrom
fleet/update-cell-skip-removed-dependents

Conversation

@sokra

@sokra sokra commented Oct 20, 2026

Copy link
Copy Markdown
Member

What?

invalidate_cell_dependents in turbo-tasks-backend no longer dirties a dependent task when none of the invalidated dependency keys are still current or outdated dependencies of that task.

Why?

A cell's dependents are collected while the cell task is locked, and each dependent is locked separately afterwards. In between, the dependent can finish an execution that no longer reads the cell, and cleanup_old_edges removes the dependency. For hashed cells, the dependent may also track only other keys of the same cell.

The code was meant to skip such removed dependencies, but its continue only continued the inner per-key loop. So the task was always marked dirty and rescheduled after the loop, even when every key had been removed.

Follow-up to #100446 (comment).

How?

Every key is a separate dependency. Keys are only grouped per dependent to reduce task locking, so the decision is made per task after all keys have been checked:

  • An outdated dependency hasn't been read in the current execution yet. It marks the task dirty, but not stale, so the task is no longer treated as a recomputation (unchanged behavior).
  • A current dependency has already been read. It marks the task stale, which also makes it dirty (unchanged behavior).
  • A removed dependency contributes nothing.

The task is only dirtied if at least one key is outdated or current. Installing the new cell content, notifying waiters, and processing the aggregation queue happen regardless.

The race can't be triggered reliably through the public turbo-tasks API, so this adds backend unit tests that set up dependency state directly and call invalidate_cell_dependents. They cover:

  • all dependencies removed (keyed and unkeyed)
  • removed and current dependencies mixed
  • a current unkeyed dependency
  • an outdated dependency

Verification

  • The two removed-dependency tests fail without the fix and pass with it.
  • cargo test -p turbo-tasks-backend
  • cargo test -p turbo-tasks-backend --lib --features task_dirty_cause invalidate_cell_dependents_tests
  • cargo clippy -p turbo-tasks-backend --tests

Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Tests Passed

Commit: 3644fea

@github-actions github-actions Bot added created-by: Turbopack team PRs by the Turbopack team. Turbopack Related to Turbopack with Next.js. labels Oct 20, 2026
@lukesandberg

Copy link
Copy Markdown
Contributor

Some benchmarking results would be nice but are difficult. im guessing this saves executing dead tasks which isn't that common... maybe?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

created-by: Turbopack team PRs by the Turbopack team. Turbopack Related to Turbopack with Next.js.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants