next.js
86d92b94 - turbo-tasks-backend: check access in track_modification and only track Data on serialization invalidation (#99581)

Commit
8 days ago
turbo-tasks-backend: check access in track_modification and only track Data on serialization invalidation (#99581) ### What? Turbo-tasks backend: when a task guard marks a category (Data or Meta) of a persistent task as modified, it now checks that the guard was acquired with that category. Serialization invalidation now marks only Data as modified. ### Why? Marking a category as modified means the next snapshot writes the in-memory copy of that category to disk. If the category was never restored, the in-memory copy is empty, and the snapshot overwrites the real persisted data. `invalidate_serialization` hit exactly this case: - The backend acquires the task with Data access only. - The guard then marked both Data and Meta as modified, bypassing any access check. - After an eviction, mutating a `State` stored in a cell therefore persisted an empty Meta. - On the next restore the task's output was gone, so the task silently re-executed. ### How? - **Access check.** `TaskGuardImpl::track_modification` runs the existing debug access assertion before delegating for non-transient tasks. Transient tasks are still skipped. - Every caller is now covered, including the macro-generated accessors and the hand-written cell-data mutators. - Any future mismatch fails loudly in debug builds and tests instead of corrupting persisted state. - **Data only for serialization invalidation.** Serialization invalidation concerns cell data (for example a `State` mutated in place), so it now marks only Data, through the checked guard path rather than the raw storage guard. - **Audit of the remaining callers.** None of them track a category they don't hold: - GC tombstoning and resurrection acquire `All`. - The cell-data mutators check Data. - New-task initialization restores `All`. - The generated accessors derive the check and the tracked category from the same field category. - **Regression test.** `tests/invalidate_serialization.rs` runs a task whose cell holds a `State` and snapshots/evicts it (asserting that both Data and Meta were evicted). It then mutates the state, snapshots again, and asserts the task is served from cache without re-executing. - The test deliberately has no readers of the state. A re-executing dependent would restore the task's Meta before the snapshot and hide the bug. - With the old tracking it fails on every run; with the fix it passes. Verified with `cargo test -p turbo-tasks-backend` (debug build, so the access assertions are active), plus clippy and rustfmt. <!-- NEXT_JS_LLM --> <!-- fleet c78c9059-116c-46e3-8ab3-5adc412156f1 --> Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Author
Parents
Loading