Turbo Tasks: Concepts
Introduction
The Turbo Tasks library provides is an incremental computation system that uses macros and types to automate the caching process. Externally, it is known as the Turbo engine.
It draws inspiration from webpack, Salsa (which powers Rust-Analyzer and Ruff), Parcel, the Rust compiler’s query system, Adapton, and many others.
Functions and Tasks
#[turbo_tasks::function]
s are memoized functions within the build process. An instance of a function with arguments is called a task. They are responsible for:
- Tracking Dependencies: Each task keeps track of its dependencies to determine when a recomputation is necessary. Dependencies are tracked when a
Vc<T>
(Value Cell) is awaited. - Recomputing Changes: When a dependency changes, the affected tasks are automatically recomputed.
- Parallel Execution: Every task is spawned as a Tokio task, which uses Tokio's multithreaded work-stealing executor.
Task Graph
All tasks and their dependencies form a task graph.
This graph is crucial for invalidation propagation. When a task is invalidated, the changes propagate through the graph, triggering rebuilds where necessary.
Incremental Builds
The Turbo engine employs a bottom-up approach for incremental builds.
By rebuilding invalidated tasks, only the parts of the graph affected by changes are rebuilt, leaving untouched parts intact. No work is done for unchanged parts.