Skip to content

Commit 056be10

Browse files
committed
statefulness is important to track
1 parent 23ed3c5 commit 056be10

11 files changed

Lines changed: 76 additions & 6 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,6 +1887,10 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
18871887
)));
18881888
debug_assert!(old.is_none(), "InProgress already exists");
18891889

1890+
// Reset session-stateful flag; it will be re-set during execution if the task
1891+
// still writes session-stateful cells.
1892+
task.set_has_session_stateful_cells(false);
1893+
18901894
// Make all current collectibles outdated (remove left-over outdated collectibles)
18911895
enum Collectible {
18921896
Current(CollectibleRef, i32),
@@ -3045,6 +3049,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
30453049
task_id: TaskId,
30463050
cell: CellId,
30473051
is_serializable_cell_content: bool,
3052+
is_session_stateful: bool,
30483053
content: CellContent,
30493054
updated_key_hashes: Option<SmallVec<[u64; 2]>>,
30503055
verification_mode: VerificationMode,
@@ -3055,6 +3060,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
30553060
cell,
30563061
content,
30573062
is_serializable_cell_content,
3063+
is_session_stateful,
30583064
updated_key_hashes,
30593065
verification_mode,
30603066
self.execute_context(turbo_tasks),
@@ -3607,6 +3613,7 @@ impl<B: BackingStorage> Backend for TurboTasksBackend<B> {
36073613
task_id: TaskId,
36083614
cell: CellId,
36093615
is_serializable_cell_content: bool,
3616+
is_session_stateful: bool,
36103617
content: CellContent,
36113618
updated_key_hashes: Option<SmallVec<[u64; 2]>>,
36123619
verification_mode: VerificationMode,
@@ -3616,6 +3623,7 @@ impl<B: BackingStorage> Backend for TurboTasksBackend<B> {
36163623
task_id,
36173624
cell,
36183625
is_serializable_cell_content,
3626+
is_session_stateful,
36193627
content,
36203628
updated_key_hashes,
36213629
verification_mode,

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ impl UpdateCellOperation {
5555
cell: CellId,
5656
content: CellContent,
5757
is_serializable_cell_content: bool,
58+
is_session_stateful: bool,
5859
updated_key_hashes: Option<SmallVec<[u64; 2]>>,
5960
#[cfg(feature = "verify_determinism")] verification_mode: VerificationMode,
6061
#[cfg(not(feature = "verify_determinism"))] _verification_mode: VerificationMode,
@@ -68,6 +69,10 @@ impl UpdateCellOperation {
6869

6970
let mut task = ctx.task(task_id, TaskDataCategory::All);
7071

72+
if is_session_stateful {
73+
task.set_has_session_stateful_cells(true);
74+
}
75+
7176
// We need to detect recomputation, because here the content has not actually changed (even
7277
// if it's not equal to the old content, as not all values implement Eq). We have to
7378
// assume that tasks are deterministic and pure.

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ struct TaskStorageSchema {
187187
#[field(storage = "flag", category = "transient")]
188188
stateful: bool,
189189

190+
/// Whether this task has cells containing session-stateful values (values with
191+
/// non-serializable interior state that accumulates during a session). Tasks with
192+
/// this flag set cannot be evicted mid-session.
193+
#[field(storage = "flag", category = "transient")]
194+
has_session_stateful_cells: bool,
195+
190196
// =========================================================================
191197
// CHILDREN & AGGREGATION (meta)
192198
// =========================================================================
@@ -391,7 +397,9 @@ pub enum UnevictableReason {
391397
TransientData,
392398
TransientUppers,
393399
SessionState,
400+
SessionStateful,
394401
Modified,
402+
NothingToEvict,
395403
}
396404

397405
/// Eviction level for a task after a snapshot.
@@ -447,7 +455,11 @@ impl TaskStorage {
447455
&& !flags.data_modified()
448456
&& !flags.data_modified_during_snapshot();
449457
if !data_evictable {
450-
return Evictability::No(UnevictableReason::Modified);
458+
return Evictability::No(if flags.data_restored() {
459+
UnevictableReason::Modified
460+
} else {
461+
UnevictableReason::NothingToEvict
462+
});
451463
}
452464

453465
// Data-category fields with `filter_transient` lose entries referencing transient
@@ -497,6 +509,9 @@ impl TaskStorage {
497509
{
498510
return Evictability::No(UnevictableReason::SessionState);
499511
}
512+
if flags.has_session_stateful_cells() {
513+
return Evictability::No(UnevictableReason::SessionStateful);
514+
}
500515
if meta_evictable {
501516
// Session-dependent tasks have transient state (current_session_clean flag,
502517
// Dirtyness::SessionDependent) that would be lost on full eviction.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ impl DiskFileSystemInner {
557557

558558
#[derive(Clone, ValueToString)]
559559
#[value_to_string(self.inner.name)]
560-
#[turbo_tasks::value(cell = "new", eq = "manual")]
560+
#[turbo_tasks::value(cell = "new", eq = "manual", session_stateful)]
561561
pub struct DiskFileSystem {
562562
inner: Arc<DiskFileSystemInner>,
563563
}

turbopack/crates/turbo-tasks-macros/src/primitive_macro.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub fn primitive(input: TokenStream) -> TokenStream {
6666
},
6767
new_value_type,
6868
/* has_serialization */ quote! { true },
69+
/* session_stateful */ false,
6970
);
7071

7172
let value_default_impl = quote! {

turbopack/crates/turbo-tasks-macros/src/value_macro.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ struct ValueArguments {
8080
transparent: bool,
8181
/// Should we `#[derive(turbo_tasks::OperationValue)]`?
8282
operation: Option<Span>,
83+
/// Whether this value has session-dependent interior state that survives serialization
84+
/// but would be lost on eviction/restore mid-session.
85+
session_stateful: bool,
8386
}
8487

8588
impl Parse for ValueArguments {
@@ -91,6 +94,7 @@ impl Parse for ValueArguments {
9194
manual_eq: false,
9295
transparent: false,
9396
operation: None,
97+
session_stateful: false,
9498
};
9599
let punctuated = input.parse_terminated(Meta::parse, Token![,])?;
96100
for meta in punctuated {
@@ -148,6 +152,9 @@ impl Parse for ValueArguments {
148152
("transparent", Meta::Path(_)) => {
149153
result.transparent = true;
150154
}
155+
("session_stateful", Meta::Path(_)) => {
156+
result.session_stateful = true;
157+
}
151158
("operation", Meta::Path(path)) => {
152159
result.operation = Some(path.span());
153160
}
@@ -156,8 +163,8 @@ impl Parse for ValueArguments {
156163
&meta,
157164
format!(
158165
"unexpected {meta:?}, expected \"shared\", \"into\", \
159-
\"serialization\", \"cell\", \"eq\", \"transparent\", or \
160-
\"operation\""
166+
\"serialization\", \"cell\", \"eq\", \"transparent\", \
167+
\"session_stateful\", or \"operation\""
161168
),
162169
));
163170
}
@@ -177,6 +184,7 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {
177184
manual_eq,
178185
transparent,
179186
operation,
187+
session_stateful,
180188
} = parse_macro_input!(args as ValueArguments);
181189

182190
let mut struct_attributes = vec![quote! {
@@ -388,6 +396,7 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {
388396
cell_mode,
389397
new_value_type,
390398
has_serialization,
399+
session_stateful,
391400
);
392401

393402
let expanded = quote! {
@@ -414,6 +423,7 @@ pub fn value_type_and_register(
414423
cell_mode: proc_macro2::TokenStream,
415424
new_value_type: proc_macro2::TokenStream,
416425
has_serialization: proc_macro2::TokenStream,
426+
session_stateful: bool,
417427
) -> proc_macro2::TokenStream {
418428
let value_type_ident = get_value_type_ident(ident);
419429

@@ -441,6 +451,10 @@ pub fn value_type_and_register(
441451
fn has_serialization() -> bool {
442452
#has_serialization
443453
}
454+
455+
fn is_session_stateful() -> bool {
456+
#session_stateful
457+
}
444458
}
445459
}
446460
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ impl TurboTasksApi for VcStorage {
277277
task: TaskId,
278278
index: CellId,
279279
_is_serializable_cell_content: bool,
280+
_is_session_stateful: bool,
280281
content: CellContent,
281282
_updated_key_hashes: Option<SmallVec<[u64; 2]>>,
282283
_verification_mode: VerificationMode,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ pub trait Backend: Sync + Send {
589589
task: TaskId,
590590
index: CellId,
591591
is_serializable_cell_content: bool,
592+
is_session_stateful: bool,
592593
content: CellContent,
593594
updated_key_hashes: Option<SmallVec<[u64; 2]>>,
594595
verification_mode: VerificationMode,

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ pub trait TurboTasksApi: TurboTasksCallApi + Sync + Send {
172172
task: TaskId,
173173
index: CellId,
174174
is_serializable_cell_content: bool,
175+
is_session_stateful: bool,
175176
content: CellContent,
176177
updated_key_hashes: Option<SmallVec<[u64; 2]>>,
177178
verification_mode: VerificationMode,
@@ -1568,6 +1569,7 @@ impl<B: Backend + 'static> TurboTasksApi for TurboTasks<B> {
15681569
task: TaskId,
15691570
index: CellId,
15701571
is_serializable_cell_content: bool,
1572+
is_session_stateful: bool,
15711573
content: CellContent,
15721574
updated_key_hashes: Option<SmallVec<[u64; 2]>>,
15731575
verification_mode: VerificationMode,
@@ -1576,6 +1578,7 @@ impl<B: Backend + 'static> TurboTasksApi for TurboTasks<B> {
15761578
task,
15771579
index,
15781580
is_serializable_cell_content,
1581+
is_session_stateful,
15791582
content,
15801583
updated_key_hashes,
15811584
verification_mode,
@@ -2021,6 +2024,7 @@ pub struct CurrentCellRef {
20212024
current_task: TaskId,
20222025
index: CellId,
20232026
is_serializable_cell_content: bool,
2027+
is_session_stateful: bool,
20242028
}
20252029

20262030
type VcReadTarget<T> = <<T as VcValueType>::Read as VcRead<T>>::Target;
@@ -2069,6 +2073,7 @@ impl CurrentCellRef {
20692073
self.current_task,
20702074
self.index,
20712075
self.is_serializable_cell_content,
2076+
self.is_session_stateful,
20722077
CellContent(Some(update)),
20732078
updated_key_hashes,
20742079
VerificationMode::EqualityCheck,
@@ -2213,6 +2218,7 @@ impl CurrentCellRef {
22132218
self.current_task,
22142219
self.index,
22152220
self.is_serializable_cell_content,
2221+
self.is_session_stateful,
22162222
CellContent(Some(SharedReference::new(triomphe::Arc::new(new_value)))),
22172223
None,
22182224
verification_mode,
@@ -2259,6 +2265,7 @@ impl CurrentCellRef {
22592265
self.current_task,
22602266
self.index,
22612267
self.is_serializable_cell_content,
2268+
self.is_session_stateful,
22622269
CellContent(Some(shared_ref)),
22632270
None,
22642271
verification_mode,
@@ -2279,10 +2286,18 @@ fn extract_sr_value<T: VcValueType>(sr: &SharedReference) -> &T {
22792286
}
22802287

22812288
pub fn find_cell_by_type<T: VcValueType>() -> CurrentCellRef {
2282-
find_cell_by_id(T::get_value_type_id(), T::has_serialization())
2289+
find_cell_by_id(
2290+
T::get_value_type_id(),
2291+
T::has_serialization(),
2292+
T::is_session_stateful(),
2293+
)
22832294
}
22842295

2285-
pub fn find_cell_by_id(ty: ValueTypeId, is_serializable_cell_content: bool) -> CurrentCellRef {
2296+
pub fn find_cell_by_id(
2297+
ty: ValueTypeId,
2298+
is_serializable_cell_content: bool,
2299+
is_session_stateful: bool,
2300+
) -> CurrentCellRef {
22862301
CURRENT_TASK_STATE.with(|ts| {
22872302
let current_task = current_task("celling turbo_tasks values");
22882303
let mut ts = ts.write().unwrap();
@@ -2294,6 +2309,7 @@ pub fn find_cell_by_id(ty: ValueTypeId, is_serializable_cell_content: bool) -> C
22942309
current_task,
22952310
index: CellId { type_id: ty, index },
22962311
is_serializable_cell_content,
2312+
is_session_stateful,
22972313
}
22982314
})
22992315
}

turbopack/crates/turbo-tasks/src/task/function.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,10 @@ mod tests {
433433
fn has_serialization() -> bool {
434434
false
435435
}
436+
437+
fn is_session_stateful() -> bool {
438+
false
439+
}
436440
}
437441

438442
trait AsyncTrait {

0 commit comments

Comments
 (0)