Skip to content

Commit bdf1129

Browse files
authored
docs(turbopack): Move singleton pattern documentation from mdbook to rustdoc (#91175)
Copied over from https://turbopack-rust-docs.vercel.sh/turbo-engine/singleton.html with minimal changes. ![Screenshot 2026-03-10 at 5.53.09 PM.png](https://app.graphite.com/user-attachments/assets/34b36854-1643-4daf-a4e6-7baf43ef2790.png)
1 parent 96b6c00 commit bdf1129

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

turbopack/crates/turbo-tasks/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ It defines some derived elements from that:
1414
- **Tasks:** An instance of a function together with its arguments.
1515
- **[`Vc`s ("Value Cells")][`Vc`]:** References to locations associated with tasks where values are stored. The contents of a cell can change after the reexecution of a function due to invalidation. A [`Vc`] can be read to get [a read-only reference][crate::ReadRef] to the stored data, representing a snapshot of that cell at that point in time.
1616

17+
There are a few design patterns that are commonly used with Turbo Tasks:
18+
- **[Singleton Pattern][crate::_singleton_pattern]:** Use a private constructor function to ensure a 1:1 mapping between values and value cells.
19+
1720
[blog-post]: https://nextjs.org/blog/turbopack-incremental-computation
1821
[cell id equality]: crate::ResolvedVc#equality--hashing
1922
[`Vc`]: crate::Vc
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Singleton Pattern
2+
3+
In the context of turbo-tasks, the singleton pattern can be used to intern a value into a `Vc`. This ensures that for a single value, there is exactly one resolved `Vc`. This makes it safer to compare [`ResolvedVc`]s for equality and use them as keys in [`IndexMap`]s or [`HashMap`]s.
4+
5+
[`IndexMap`]: indexmap::map::IndexMap
6+
[`HashMap`]: std::collections::HashMap
7+
8+
## Usage
9+
10+
To use the singleton pattern in turbo-tasks:
11+
12+
1. Make the `.cell()` method private (Use [`#[turbo_tasks::value]`][value] instead of [`#[turbo_tasks::value(shared)]`][value]).
13+
2. Only call the `.cell()` method in a single [`#[turbo_tasks::function]`][function] which acts as a constructor.
14+
3. The [constructor arguments][TaskInput] act as a key for the constructor task which ensures that the same value is always celled in the same task.
15+
4. Keep in mind that you should only compare `ResolvedVc`s by equality. Unresolved `Vc`s might not be equal to each other.
16+
17+
[value]: crate::value
18+
[function]: crate::function
19+
[TaskInput]: crate::TaskInput
20+
21+
## Example
22+
23+
```ignore
24+
#[turbo_tasks::value]
25+
struct SingletonString {
26+
value: String,
27+
}
28+
29+
#[turbo_tasks::value_impl]
30+
impl SingletonString {
31+
#[turbo_tasks::function]
32+
fn new(value: String) -> Vc<SingletonString> {
33+
Self { value }.cell()
34+
}
35+
}
36+
37+
#[test]
38+
fn test_singleton() {
39+
let a1 = SingletonString::new("a".to_string()).to_resolved().await?;
40+
let a2 = SingletonString::new("a".to_string()).to_resolved().await?;
41+
let b = SingletonString::new("b".to_string()).to_resolved().await?;
42+
assert_eq!(a1, a2); // Resolved Vcs are equal
43+
assert_ne!(a1, b);
44+
45+
let set = HashSet::from([a1, a2, b]);
46+
assert_eq!(set.len(), 2); // Only two different values
47+
}
48+
```
49+
50+
In this example, `SingletonString` is a struct that contains a single `String` value. The `new` function acts as a constructor for `SingletonString`, ensuring that the same string value is always celled in the same task.

turbopack/crates/turbo-tasks/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ macro_rules! fxindexset {
159159
};
160160
}
161161

162+
#[doc = include_str!("../singleton_pattern.md")]
163+
pub mod _singleton_pattern {}
164+
162165
#[doc = include_str!("../function.md")]
163166
#[rustfmt::skip]
164167
pub use turbo_tasks_macros::function;

0 commit comments

Comments
 (0)