Skip to content

Commit bd5f4f7

Browse files
committed
Turbopack: avoid removing cells for erroring tasks
avoid flagging tasks dirty when removing cells
1 parent 38ac035 commit bd5f4f7

2 files changed

Lines changed: 65 additions & 71 deletions

File tree

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

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@ impl<B: BackingStorage> Drop for OperationGuard<'_, B> {
418418
/// Intermediate result of step 1 of task execution completion.
419419
struct TaskExecutionCompletePrepareResult {
420420
pub new_children: FxHashSet<TaskId>,
421-
pub removed_data: Vec<CachedDataItem>,
422421
pub is_now_immutable: bool,
423422
#[cfg(feature = "verify_determinism")]
424423
pub no_output_set: bool,
@@ -1793,11 +1792,13 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
17931792
stale = tracing::field::Empty,
17941793
)
17951794
.entered();
1795+
1796+
let is_error = result.is_err();
1797+
17961798
let mut ctx = self.execute_context(turbo_tasks);
17971799

17981800
let Some(TaskExecutionCompletePrepareResult {
17991801
new_children,
1800-
mut removed_data,
18011802
is_now_immutable,
18021803
#[cfg(feature = "verify_determinism")]
18031804
no_output_set,
@@ -1852,6 +1853,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
18521853
return true;
18531854
}
18541855

1856+
let mut removed_data = Vec::new();
18551857
if self.task_execution_completed_finish(
18561858
&mut ctx,
18571859
task_id,
@@ -1867,9 +1869,15 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
18671869
return true;
18681870
}
18691871

1870-
drop(removed_data);
1872+
self.task_execution_completed_cleanup(
1873+
&mut ctx,
1874+
task_id,
1875+
cell_counters,
1876+
is_error,
1877+
&mut removed_data,
1878+
);
18711879

1872-
self.task_execution_completed_cleanup(&mut ctx, task_id);
1880+
drop(removed_data);
18731881

18741882
false
18751883
}
@@ -1890,7 +1898,6 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
18901898
if matches!(in_progress, InProgressState::Canceled) {
18911899
return Some(TaskExecutionCompletePrepareResult {
18921900
new_children: Default::default(),
1893-
removed_data: Default::default(),
18941901
is_now_immutable: false,
18951902
#[cfg(feature = "verify_determinism")]
18961903
no_output_set: false,
@@ -1982,7 +1989,6 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
19821989

19831990
let mut queue = AggregationUpdateQueue::new();
19841991

1985-
let mut removed_data = Vec::new();
19861992
let mut old_edges = Vec::new();
19871993

19881994
let has_children = !new_children.is_empty();
@@ -2021,27 +2027,6 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
20212027
old_edges.extend(iter_many!(task, Child { task } => task).map(OutdatedEdge::Child));
20222028
}
20232029

2024-
// Remove no longer existing cells and
2025-
// find all outdated data items (removed cells, outdated edges)
2026-
// Note: For persistent tasks we only want to call extract_if when there are actual cells to
2027-
// remove to avoid tracking that as modification.
2028-
if task_id.is_transient() || iter_many!(task, CellData { cell }
2029-
if cell_counters.get(&cell.type_id).is_none_or(|start_index| cell.index >= *start_index) => cell
2030-
).count() > 0 {
2031-
removed_data.extend(task.extract_if(CachedDataItemType::CellData, |key, _| {
2032-
matches!(key, CachedDataItemKey::CellData { cell } if cell_counters
2033-
.get(&cell.type_id).is_none_or(|start_index| cell.index >= *start_index))
2034-
}));
2035-
}
2036-
if task_id.is_transient() || iter_many!(task, TransientCellData { cell }
2037-
if cell_counters.get(&cell.type_id).is_none_or(|start_index| cell.index >= *start_index) => cell
2038-
).count() > 0 {
2039-
removed_data.extend(task.extract_if(CachedDataItemType::TransientCellData, |key, _| {
2040-
matches!(key, CachedDataItemKey::TransientCellData { cell } if cell_counters
2041-
.get(&cell.type_id).is_none_or(|start_index| cell.index >= *start_index))
2042-
}));
2043-
}
2044-
20452030
old_edges.extend(
20462031
task.iter(CachedDataItemType::OutdatedCollectible)
20472032
.filter_map(|(key, value)| match (key, value) {
@@ -2056,25 +2041,6 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
20562041
if self.should_track_dependencies() {
20572042
old_edges.extend(iter_many!(task, OutdatedCellDependency { target } => OutdatedEdge::CellDependency(target)));
20582043
old_edges.extend(iter_many!(task, OutdatedOutputDependency { target } => OutdatedEdge::OutputDependency(target)));
2059-
old_edges.extend(
2060-
iter_many!(task, CellDependent { cell, task } => (cell, task)).filter_map(
2061-
|(cell, task)| {
2062-
if cell_counters
2063-
.get(&cell.type_id)
2064-
.is_none_or(|start_index| cell.index >= *start_index)
2065-
&& let Some(old_counter) = old_counters.get(&cell.type_id)
2066-
&& cell.index < *old_counter
2067-
{
2068-
return Some(OutdatedEdge::RemovedCellDependent {
2069-
task_id: task,
2070-
#[cfg(feature = "trace_task_dirty")]
2071-
value_type_id: cell.type_id,
2072-
});
2073-
}
2074-
None
2075-
},
2076-
),
2077-
);
20782044
}
20792045

20802046
// Check if output need to be updated
@@ -2151,7 +2117,6 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
21512117

21522118
Some(TaskExecutionCompletePrepareResult {
21532119
new_children,
2154-
removed_data,
21552120
is_now_immutable,
21562121
#[cfg(feature = "verify_determinism")]
21572122
no_output_set,
@@ -2488,14 +2453,66 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
24882453
reschedule
24892454
}
24902455

2491-
fn task_execution_completed_cleanup(&self, ctx: &mut impl ExecuteContext<'_>, task_id: TaskId) {
2456+
fn task_execution_completed_cleanup(
2457+
&self,
2458+
ctx: &mut impl ExecuteContext<'_>,
2459+
task_id: TaskId,
2460+
cell_counters: &AutoMap<ValueTypeId, u32, BuildHasherDefault<FxHasher>, 8>,
2461+
is_error: bool,
2462+
removed_data: &mut Vec<CachedDataItem>,
2463+
) {
24922464
let mut task = ctx.task(task_id, TaskDataCategory::All);
2465+
2466+
// An error is potentially caused by a eventual consistency, so we avoid updating cells
2467+
// after an error as it is likely transient and we want to keep the dependent tasks
2468+
// clean to avoid re-executions.
2469+
if !is_error {
2470+
// Remove no longer existing cells and
2471+
// find all outdated data items (removed cells, outdated edges)
2472+
// Note: For persistent tasks we only want to call extract_if when there are actual
2473+
// cells to remove to avoid tracking that as modification.
2474+
// Note: We do not mark the tasks as dirty here, as these tasks are unused or stale
2475+
// anyway and we want to avoid needless re-executions. When the cells become
2476+
// used again, they are invalidated from the update cell operation.
2477+
if task_id.is_transient()
2478+
|| iter_many!(task, CellData { cell }
2479+
if cell_counters
2480+
.get(&cell.type_id)
2481+
.is_none_or(|start_index| cell.index >= *start_index)
2482+
=> cell)
2483+
.count()
2484+
> 0
2485+
{
2486+
removed_data.extend(task.extract_if(CachedDataItemType::CellData, |key, _| {
2487+
matches!(key, CachedDataItemKey::CellData { cell } if cell_counters.get(&cell.type_id).is_none_or(|start_index| cell.index >= *start_index))
2488+
}));
2489+
}
2490+
if task_id.is_transient()
2491+
|| iter_many!(task, TransientCellData { cell }
2492+
if cell_counters
2493+
.get(&cell.type_id)
2494+
.is_none_or(|start_index| cell.index >= *start_index)
2495+
=> cell)
2496+
.count()
2497+
> 0
2498+
{
2499+
removed_data.extend(task.extract_if(
2500+
CachedDataItemType::TransientCellData,
2501+
|key, _| {
2502+
matches!(key, CachedDataItemKey::TransientCellData { cell } if cell_counters.get(&cell.type_id).is_none_or(|start_index| cell.index >= *start_index))
2503+
},
2504+
));
2505+
}
2506+
}
2507+
2508+
// Shrink memory usage
24932509
task.shrink_to_fit(CachedDataItemType::CellData);
24942510
task.shrink_to_fit(CachedDataItemType::TransientCellData);
24952511
task.shrink_to_fit(CachedDataItemType::CellTypeMaxIndex);
24962512
task.shrink_to_fit(CachedDataItemType::CellDependency);
24972513
task.shrink_to_fit(CachedDataItemType::OutputDependency);
24982514
task.shrink_to_fit(CachedDataItemType::CollectiblesDependency);
2515+
24992516
drop(task);
25002517
}
25012518

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

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ use rustc_hash::FxHashSet;
55
use smallvec::SmallVec;
66
use turbo_tasks::TaskId;
77

8-
#[cfg(feature = "trace_task_dirty")]
9-
use crate::backend::operation::invalidate::TaskDirtyCause;
108
use crate::{
119
backend::{
1210
TaskDataCategory, get, get_many,
@@ -16,7 +14,6 @@ use crate::{
1614
AggregationUpdateJob, AggregationUpdateQueue, InnerOfUppersLostFollowersJob,
1715
get_aggregation_number, get_uppers, is_aggregating_node,
1816
},
19-
invalidate::make_task_dirty,
2017
},
2118
storage::update_count,
2219
},
@@ -45,11 +42,6 @@ pub enum OutdatedEdge {
4542
CellDependency(CellRef),
4643
OutputDependency(TaskId),
4744
CollectiblesDependency(CollectiblesRef),
48-
RemovedCellDependent {
49-
task_id: TaskId,
50-
#[cfg(feature = "trace_task_dirty")]
51-
value_type_id: turbo_tasks::ValueTypeId,
52-
},
5345
}
5446

5547
impl CleanupOldEdgesOperation {
@@ -224,21 +216,6 @@ impl Operation for CleanupOldEdgesOperation {
224216
});
225217
}
226218
}
227-
OutdatedEdge::RemovedCellDependent {
228-
task_id,
229-
#[cfg(feature = "trace_task_dirty")]
230-
value_type_id,
231-
} => {
232-
make_task_dirty(
233-
task_id,
234-
#[cfg(feature = "trace_task_dirty")]
235-
TaskDirtyCause::CellRemoved {
236-
value_type: value_type_id,
237-
},
238-
queue,
239-
ctx,
240-
);
241-
}
242219
}
243220
}
244221

0 commit comments

Comments
 (0)