Skip to content

Commit 94bd15c

Browse files
committed
simplify settings again
1 parent cf8bacd commit 94bd15c

12 files changed

Lines changed: 343 additions & 401 deletions

File tree

crates/next-api/src/project.rs

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -625,21 +625,17 @@ impl ProjectContainer {
625625
.start_watching_with_invalidation_reason(watch.poll_interval)
626626
.await?;
627627
} else {
628-
project_fs
629-
.invalidate_with_reason(|path| invalidation::Initialize {
630-
// this path is just used for display purposes
631-
path: RcStr::from(path.to_string_lossy()),
632-
})
633-
.await?;
628+
project_fs.invalidate_with_reason(|path| invalidation::Initialize {
629+
// this path is just used for display purposes
630+
path: RcStr::from(path.to_string_lossy()),
631+
});
634632
}
635633
let output_fs = output_fs_operation(project)
636634
.read_strongly_consistent()
637635
.await?;
638-
output_fs
639-
.invalidate_with_reason(|path| invalidation::Initialize {
640-
path: RcStr::from(path.to_string_lossy()),
641-
})
642-
.await?;
636+
output_fs.invalidate_with_reason(|path| invalidation::Initialize {
637+
path: RcStr::from(path.to_string_lossy()),
638+
});
643639
Ok(())
644640
}
645641
.instrument(span_clone)
@@ -774,20 +770,16 @@ impl ProjectContainer {
774770
.start_watching_with_invalidation_reason(watch.poll_interval)
775771
.await?;
776772
} else {
777-
project_fs
778-
.invalidate_with_reason(|path| invalidation::Initialize {
779-
// this path is just used for display purposes
780-
path: RcStr::from(path.to_string_lossy()),
781-
})
782-
.await?;
773+
project_fs.invalidate_with_reason(|path| invalidation::Initialize {
774+
// this path is just used for display purposes
775+
path: RcStr::from(path.to_string_lossy()),
776+
});
783777
}
784778
}
785779
if !ReadRef::ptr_eq(&prev_output_fs, &output_fs) {
786-
prev_output_fs
787-
.invalidate_with_reason(|path| invalidation::Initialize {
788-
path: RcStr::from(path.to_string_lossy()),
789-
})
790-
.await?;
780+
prev_output_fs.invalidate_with_reason(|path| invalidation::Initialize {
781+
path: RcStr::from(path.to_string_lossy()),
782+
});
791783
}
792784

793785
Ok(())

crates/next-napi-bindings/src/next_api/project.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,19 +1246,15 @@ async fn invalidate_deferred_entry_source_dirs_after_callback(
12461246

12471247
if paths_to_invalidate.is_empty() {
12481248
// Fallback to full invalidation when app dir paths are unavailable.
1249-
project_fs
1250-
.invalidate_with_reason(|path| invalidation::Initialize {
1251-
path: RcStr::from(path.to_string_lossy()),
1252-
})
1253-
.await?;
1249+
project_fs.invalidate_with_reason(|path| invalidation::Initialize {
1250+
path: RcStr::from(path.to_string_lossy()),
1251+
});
12541252
} else {
1255-
project_fs
1256-
.invalidate_path_and_children_with_reason(paths_to_invalidate, |path| {
1257-
invalidation::Initialize {
1258-
path: RcStr::from(path.to_string_lossy()),
1259-
}
1260-
})
1261-
.await?;
1253+
project_fs.invalidate_path_and_children_with_reason(paths_to_invalidate, |path| {
1254+
invalidation::Initialize {
1255+
path: RcStr::from(path.to_string_lossy()),
1256+
}
1257+
});
12621258
}
12631259

12641260
Ok(())

turbopack/crates/turbo-tasks-backend/src/backend/cell_data.rs

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ use turbo_bincode::{
3232
TurboBincodeDecode, TurboBincodeDecoder, TurboBincodeEncode, TurboBincodeEncoder,
3333
impl_decode_for_turbo_bincode_decode, impl_encode_for_turbo_bincode_encode,
3434
};
35-
use turbo_tasks::{CellId, SharedReference, ShrinkToFit, ValueTypePersistence, registry};
35+
use turbo_tasks::{
36+
CellId, Evictability, SharedReference, ShrinkToFit, ValueTypePersistence, registry,
37+
};
3638

3739
use crate::backend::storage_schema::{DropPartial, DropPartialOutcome};
3840

@@ -50,37 +52,23 @@ impl CellData {
5052
}
5153

5254
impl DropPartial for CellData {
53-
/// Drop cells that can be cheaply reconstructed on next access, retain
54-
/// those that cannot. Called by the macro-generated `TaskStorage::drop_partial`
55+
/// Drop cells whose value type is freely evictable, retain those that
56+
/// are not. Called by the macro-generated `TaskStorage::drop_partial`
5557
/// on the data-eviction path.
5658
///
57-
/// Dropped:
58-
/// - `Persistable` — restored from disk.
59-
/// - `SkipPersist { expensive: false, .. }` — cheap to re-derive by re-running the task.
59+
/// Dropped (`Evictability::Always`): persistable cells (restored from
60+
/// disk on next access), skip cells (re-derived by re-running the task),
61+
/// and hash-only cells (re-derived; hash gates spurious invalidation).
6062
///
6163
/// Retained:
62-
/// - `SkipPersist { expensive: true, .. }` — expensive to re-derive.
63-
/// - `SessionStateful` — would lose accumulated state if dropped.
64+
/// - `Evictability::Expensive` — re-derivation is non-trivial, prefer keeping in memory.
65+
/// - `Evictability::Never` — value type holds session-scoped state that must not leave memory
66+
/// (`State<>` cells, file watchers, worker pools).
6467
fn drop_partial(&mut self) -> DropPartialOutcome {
6568
self.0.retain(
66-
|cell_id, _| match registry::get_value_type(cell_id.type_id).persistence {
67-
ValueTypePersistence::Persistable(_, _)
68-
| ValueTypePersistence::SkipPersist {
69-
expensive: false,
70-
hash_only: _,
71-
} => {
72-
// these are either persisted or determined to not be worth persisting because
73-
// they are cheap to re-derive
74-
false
75-
}
76-
ValueTypePersistence::SkipPersist {
77-
expensive: true,
78-
hash_only: _,
79-
}
80-
| ValueTypePersistence::SessionStateful => {
81-
// These are either impossible to derive or expensive so we retain.
82-
true
83-
}
69+
|cell_id, _| match registry::get_value_type(cell_id.type_id).evictability {
70+
Evictability::Always => false,
71+
Evictability::Expensive | Evictability::Never => true,
8472
},
8573
);
8674
if self.0.is_empty() {
@@ -122,9 +110,9 @@ impl ShrinkToFit for CellData {
122110

123111
impl TurboBincodeEncode for CellData {
124112
/// Writes `count-of-persistable-entries` followed by each persistable
125-
/// `(CellId, encoded-value)`. Entries whose value type is `SkipPersist`
126-
/// or `SessionStateful` (no bincode) are skipped; they will be
127-
/// reconstructed on the next task execution after restore.
113+
/// `(CellId, encoded-value)`. Entries whose value type is `Skip` or
114+
/// `HashOnly` (no bincode codec) are skipped; they will be reconstructed
115+
/// on the next task execution after restore.
128116
fn encode(&self, encoder: &mut TurboBincodeEncoder) -> Result<(), EncodeError> {
129117
// First pass: count persistable entries. One extra O(N) iteration over
130118
// the registry — cold path (snapshot time only) and the registry is a
@@ -185,16 +173,20 @@ impl_decode_for_turbo_bincode_decode!(CellData);
185173

186174
#[cfg(test)]
187175
mod tests {
188-
//! `drop_partial` must partition cells by their `ValueTypePersistence` —
189-
//! keep the non-recoverable ones, drop the rest. Tests below declare one
190-
//! value type per persistence variant and exercise every partition.
176+
//! `drop_partial` must partition cells by their `Evictability` — keep
177+
//! the non-evictable ones, drop the rest. Tests below cover every
178+
//! `(persistence, evictability)` combination the macro currently emits,
179+
//! including the `Persistable + Never` combo (e.g. `DiskFileSystem`).
191180
use turbo_tasks::{self as turbo_tasks, VcValueType};
192181

193182
use super::*;
194183

195184
#[turbo_tasks::value]
196185
struct PersistableV(#[allow(dead_code)] u32);
197186

187+
#[turbo_tasks::value(evict = "never")]
188+
struct PersistableNeverV(#[allow(dead_code)] u32);
189+
198190
#[turbo_tasks::value(serialization = "skip")]
199191
struct SkipCheapV(
200192
#[turbo_tasks(trace_ignore)]
@@ -229,16 +221,18 @@ mod tests {
229221
}
230222

231223
#[test]
232-
fn drop_partial_partitions_by_persistence() {
224+
fn drop_partial_partitions_by_evictability() {
233225
let mut data = CellData::new();
234226
data.insert(cell_of::<PersistableV>(0), dummy_ref());
227+
data.insert(cell_of::<PersistableNeverV>(0), dummy_ref());
235228
data.insert(cell_of::<SkipCheapV>(0), dummy_ref());
236229
data.insert(cell_of::<SkipExpensiveV>(0), dummy_ref());
237230
data.insert(cell_of::<SessionStatefulV>(0), dummy_ref());
238231
data.insert(cell_of::<HashOnlyV>(0), dummy_ref());
239232

240233
assert_eq!(data.drop_partial(), DropPartialOutcome::HasResidue);
241-
assert_eq!(data.len(), 2);
234+
assert_eq!(data.len(), 3);
235+
assert!(data.contains_key(&cell_of::<PersistableNeverV>(0)));
242236
assert!(data.contains_key(&cell_of::<SkipExpensiveV>(0)));
243237
assert!(data.contains_key(&cell_of::<SessionStatefulV>(0)));
244238
assert!(!data.contains_key(&cell_of::<PersistableV>(0)));
@@ -247,7 +241,7 @@ mod tests {
247241
}
248242

249243
#[test]
250-
fn drop_partial_fully_empties_when_all_recoverable() {
244+
fn drop_partial_fully_empties_when_all_evictable() {
251245
let mut data = CellData::new();
252246
data.insert(cell_of::<PersistableV>(0), dummy_ref());
253247
data.insert(cell_of::<SkipCheapV>(0), dummy_ref());
@@ -258,13 +252,14 @@ mod tests {
258252
}
259253

260254
#[test]
261-
fn drop_partial_keeps_everything_when_all_non_recoverable() {
255+
fn drop_partial_keeps_everything_when_all_non_evictable() {
262256
let mut data = CellData::new();
257+
data.insert(cell_of::<PersistableNeverV>(0), dummy_ref());
263258
data.insert(cell_of::<SkipExpensiveV>(0), dummy_ref());
264259
data.insert(cell_of::<SessionStatefulV>(0), dummy_ref());
265260

266261
assert_eq!(data.drop_partial(), DropPartialOutcome::HasResidue);
267-
assert_eq!(data.len(), 2);
262+
assert_eq!(data.len(), 3);
268263
}
269264

270265
#[test]

turbopack/crates/turbo-tasks-backend/src/backend/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::{
1414
pin::Pin,
1515
sync::{
1616
Arc, LazyLock,
17-
atomic::{AtomicBool, AtomicU64, Ordering},
17+
atomic::{AtomicBool, Ordering},
1818
},
1919
time::SystemTime,
2020
};

turbopack/crates/turbo-tasks-backend/src/backend/operation/update_cell.rs

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,7 @@ impl UpdateCellOperation {
6565
// cleared.)
6666
debug_assert!(
6767
content_hash.is_none()
68-
|| matches!(
69-
value_type.persistence,
70-
ValueTypePersistence::SkipPersist {
71-
expensive: _,
72-
hash_only: true
73-
}
74-
),
68+
|| matches!(value_type.persistence, ValueTypePersistence::HashOnly),
7569
"content_hash must only be supplied for HashOnly cells"
7670
);
7771

@@ -118,23 +112,18 @@ impl UpdateCellOperation {
118112

119113
// For HashOnly cells without available content, use hash-based comparison to
120114
// detect whether the value actually changed—avoiding unnecessary invalidation.
121-
let skip_invalidation = matches!(
122-
value_type.persistence,
123-
ValueTypePersistence::SkipPersist {
124-
expensive: _,
125-
hash_only: true
126-
}
127-
) && {
128-
let has_old_content = task.cell_data_contains(&cell);
129-
if !has_old_content {
130-
match (content_hash, task.get_cell_data_hash(&cell)) {
131-
(Some(new_hash), Some(old_hash)) => new_hash == *old_hash,
132-
_ => false,
115+
let skip_invalidation =
116+
matches!(value_type.persistence, ValueTypePersistence::HashOnly) && {
117+
let has_old_content = task.cell_data_contains(&cell);
118+
if !has_old_content {
119+
match (content_hash, task.get_cell_data_hash(&cell)) {
120+
(Some(new_hash), Some(old_hash)) => new_hash == *old_hash,
121+
_ => false,
122+
}
123+
} else {
124+
false
133125
}
134-
} else {
135-
false
136-
}
137-
};
126+
};
138127

139128
#[cfg(feature = "trace_task_dirty")]
140129
let has_updated_key_hashes = updated_key_hashes.is_some();
@@ -181,13 +170,7 @@ impl UpdateCellOperation {
181170
let old_content = task.remove_cell_data(&cell);
182171

183172
// Update cell_data_hash before dropping the task lock
184-
if matches!(
185-
value_type.persistence,
186-
ValueTypePersistence::SkipPersist {
187-
expensive: _,
188-
hash_only: true
189-
}
190-
) {
173+
if matches!(value_type.persistence, ValueTypePersistence::HashOnly) {
191174
update_cell_data_hash(&mut task, &cell, content_hash);
192175
}
193176

@@ -226,14 +209,8 @@ impl UpdateCellOperation {
226209
task.remove_cell_data(&cell)
227210
};
228211

229-
// Update cell_data_hash for non-hashonly cells.
230-
if matches!(
231-
value_type.persistence,
232-
ValueTypePersistence::SkipPersist {
233-
expensive: _,
234-
hash_only: true
235-
}
236-
) {
212+
// Update cell_data_hash for hash-only cells.
213+
if matches!(value_type.persistence, ValueTypePersistence::HashOnly) {
237214
update_cell_data_hash(&mut task, &cell, content_hash);
238215
}
239216

turbopack/crates/turbo-tasks-backend/src/backend/storage_schema.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,15 @@ struct TaskStorageSchema {
287287
// =========================================================================
288288
/// Cell data for all cells, regardless of serialization mode.
289289
///
290-
/// `CellData` is a newtype over `AutoMap<CellId, SharedReference>` whose
291-
/// bincode impl filters out entries whose value type is not
292-
/// `ValueTypePersistence::Persistable` at encode time (i.e. `SkipPersist`
293-
/// or `SessionStateful`). Those entries stay in memory but are not
294-
/// persisted — on restore the next read triggers the "cell index in range
295-
/// but data missing" recompute path. `SessionStateful` value types are
296-
/// identified on `ValueType::persistence` for future eviction handling.
290+
/// `CellData` is a newtype over `AutoMap<CellId, SharedReference>` with
291+
/// two policies driven by the value type registry:
292+
///
293+
/// - **Persistence** (encode time): only entries whose value type has
294+
/// `ValueTypePersistence::Persistable` are written to disk. `Skip` and `HashOnly` entries
295+
/// stay in memory only — on restore the next read triggers the "cell index in range but data
296+
/// missing" recompute path.
297+
/// - **Eviction** (`drop_partial`): entries are dropped iff their value type's `Evictability`
298+
/// is `Always`. `Expensive` and `Never` cells stay in memory across the eviction sweep.
297299
#[field(
298300
storage = "auto_map",
299301
category = "data",

0 commit comments

Comments
 (0)