Skip to content

Commit 9490832

Browse files
authored
Turbopack: skip db lookups on the initial build (#82405)
### What? In certain cases (e.g. on initial build) the backend knows that the backing storage has no more info than the memory cache. In these cases it can skip looking up every task on the backing storage.
1 parent 1e0f9d4 commit 9490832

File tree

3 files changed

+31
-14
lines changed

3 files changed

+31
-14
lines changed

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

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ struct TurboTasksBackendInner<B: BackingStorage> {
176176

177177
storage: Storage,
178178

179+
/// When true, the backing_storage has data that is not in the local storage.
180+
local_is_partial: AtomicBool,
181+
179182
/// Number of executing operations + Highest bit is set when snapshot is
180183
/// requested. When that bit is set, operations should pause until the
181184
/// snapshot is completed. When the bit is set and in progress counter
@@ -231,16 +234,17 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
231234
options.active_tracking = false;
232235
}
233236
let small_preallocation = options.small_preallocation;
237+
let next_task_id = backing_storage
238+
.next_free_task_id()
239+
.expect("Failed to get task id");
234240
Self {
235241
options,
236242
start_time: Instant::now(),
237243
session_id: backing_storage
238244
.next_session_id()
239245
.expect("Failed get session id"),
240246
persisted_task_id_factory: IdFactoryWithReuse::new(
241-
backing_storage
242-
.next_free_task_id()
243-
.expect("Failed to get task id"),
247+
next_task_id,
244248
TaskId::try_from(TRANSIENT_TASK_BIT - 1).unwrap(),
245249
),
246250
transient_task_id_factory: IdFactoryWithReuse::new(
@@ -250,6 +254,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
250254
persisted_task_cache_log: need_log.then(|| Sharded::new(shard_amount)),
251255
task_cache: BiMap::new(),
252256
transient_tasks: FxDashMap::default(),
257+
local_is_partial: AtomicBool::new(next_task_id != TaskId::MIN),
253258
storage: Storage::new(small_preallocation),
254259
in_progress_operations: AtomicUsize::new(0),
255260
snapshot_request: Mutex::new(SnapshotRequest::new()),
@@ -910,6 +915,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
910915
return Some(task_type);
911916
}
912917
if self.should_restore()
918+
&& self.local_is_partial.load(Ordering::Acquire)
913919
&& !task_id.is_transient()
914920
&& let Some(task_type) = unsafe {
915921
self.backing_storage
@@ -1271,16 +1277,21 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
12711277
return task_id;
12721278
}
12731279

1274-
let tx = self
1275-
.should_restore()
1280+
let check_backing_storage =
1281+
self.should_restore() && self.local_is_partial.load(Ordering::Acquire);
1282+
let tx = check_backing_storage
12761283
.then(|| self.backing_storage.start_read_transaction())
12771284
.flatten();
12781285
let task_id = {
12791286
// Safety: `tx` is a valid transaction from `self.backend.backing_storage`.
12801287
if let Some(task_id) = unsafe {
1281-
self.backing_storage
1282-
.forward_lookup_task_cache(tx.as_ref(), &task_type)
1283-
.expect("Failed to lookup task id")
1288+
check_backing_storage
1289+
.then(|| {
1290+
self.backing_storage
1291+
.forward_lookup_task_cache(tx.as_ref(), &task_type)
1292+
.expect("Failed to lookup task id")
1293+
})
1294+
.flatten()
12841295
} {
12851296
self.track_cache_hit(&task_type);
12861297
let _ = self.task_cache.try_insert(Arc::new(task_type), task_id);

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod update_output;
1111
use std::{
1212
fmt::{Debug, Formatter},
1313
mem::transmute,
14+
sync::atomic::Ordering,
1415
};
1516

1617
use serde::{Deserialize, Serialize};
@@ -113,6 +114,12 @@ where
113114
category: TaskDataCategory,
114115
) -> Vec<CachedDataItem> {
115116
if matches!(self.transaction, TransactionState::None) {
117+
let check_backing_storage = self.backend.should_restore()
118+
&& self.backend.local_is_partial.load(Ordering::Acquire);
119+
if !check_backing_storage {
120+
// If we don't need to restore, we can just return an empty vector
121+
return Vec::new();
122+
}
116123
let tx = self.backend.backing_storage.start_read_transaction();
117124
let tx = tx.map(|tx| {
118125
// Safety: self is actually valid for 'a, so it's safe to transmute 'l to 'a

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,11 @@ impl<T: KeyValueDatabase + Send + Sync + 'static> BackingStorageSealed
262262
type ReadTransaction<'l> = T::ReadTransaction<'l>;
263263

264264
fn next_free_task_id(&self) -> Result<TaskId> {
265-
Ok(TaskId::try_from(
266-
self.inner
267-
.get_infra_u32(META_KEY_NEXT_FREE_TASK_ID)
268-
.context("Unable to read next free task id from database")?
269-
.unwrap_or(1),
270-
)?)
265+
Ok(self
266+
.inner
267+
.get_infra_u32(META_KEY_NEXT_FREE_TASK_ID)
268+
.context("Unable to read next free task id from database")?
269+
.map_or(Ok(TaskId::MIN), TaskId::try_from)?)
271270
}
272271

273272
fn next_session_id(&self) -> Result<SessionId> {

0 commit comments

Comments
 (0)