Skip to content

Commit df1f762

Browse files
authored
Turbopack: Compact only at the end for short sessions (#82224)
### What? Change the compaction behavior for "short sessions" (like next build). A longer "short session" might commit to the DB multiple times (every 60s currently), which previously resulted in compactions happening after multiple commits to the database. As compactions are expensive and memory hungry, we want to avoid them until the end of the session. At the end of the session we can run it in parallel to node.js SSG.
1 parent 8377abe commit df1f762

File tree

10 files changed

+44
-13
lines changed

10 files changed

+44
-13
lines changed

crates/napi/src/next_api/project.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ pub struct NapiTurboEngineOptions {
253253
pub dependency_tracking: Option<bool>,
254254
/// Whether the project is running in a CI environment.
255255
pub is_ci: Option<bool>,
256+
/// Whether the project is running in a short session.
257+
pub is_short_session: Option<bool>,
256258
}
257259

258260
impl From<NapiWatchOptions> for WatchOptions {
@@ -434,12 +436,14 @@ pub fn project_new(
434436
let persistent_caching = turbo_engine_options.persistent_caching.unwrap_or_default();
435437
let dependency_tracking = turbo_engine_options.dependency_tracking.unwrap_or(true);
436438
let is_ci = turbo_engine_options.is_ci.unwrap_or(false);
439+
let is_short_session = turbo_engine_options.is_short_session.unwrap_or(false);
437440
let turbo_tasks = create_turbo_tasks(
438441
PathBuf::from(&options.dist_dir),
439442
persistent_caching,
440443
memory_limit,
441444
dependency_tracking,
442445
is_ci,
446+
is_short_session,
443447
)?;
444448
let turbopack_ctx = NextTurbopackContext::new(turbo_tasks.clone(), napi_callbacks);
445449

crates/napi/src/next_api/turbopack_ctx.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,15 +185,20 @@ pub fn create_turbo_tasks(
185185
_memory_limit: usize,
186186
dependency_tracking: bool,
187187
is_ci: bool,
188+
is_short_session: bool,
188189
) -> Result<NextTurboTasks> {
189190
Ok(if persistent_caching {
190191
let version_info = GitVersionInfo {
191192
describe: env!("VERGEN_GIT_DESCRIBE"),
192193
dirty: option_env!("CI").is_none_or(|value| value.is_empty())
193194
&& env!("VERGEN_GIT_DIRTY") == "true",
194195
};
195-
let (backing_storage, cache_state) =
196-
default_backing_storage(&output_path.join("cache/turbopack"), &version_info, is_ci)?;
196+
let (backing_storage, cache_state) = default_backing_storage(
197+
&output_path.join("cache/turbopack"),
198+
&version_info,
199+
is_ci,
200+
is_short_session,
201+
)?;
197202
let tt = TurboTasks::new(TurboTasksBackend::new(
198203
BackendOptions {
199204
storage_mode: Some(if std::env::var("TURBO_ENGINE_READ_ONLY").is_ok() {

packages/next/src/build/swc/generated-native.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ export interface NapiTurboEngineOptions {
212212
dependencyTracking?: boolean
213213
/** Whether the project is running in a CI environment. */
214214
isCi?: boolean
215+
/** Whether the project is running in a short session. */
216+
isShortSession?: boolean
215217
}
216218
export declare function projectNew(
217219
options: NapiProjectOptions,

packages/next/src/build/turbopack-build/impl.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export async function turbopackBuild(): Promise<{
9191
memoryLimit: config.experimental?.turbopackMemoryLimit,
9292
dependencyTracking: persistentCaching,
9393
isCi: isCI,
94+
isShortSession: true,
9495
}
9596
)
9697
try {

packages/next/src/server/dev/hot-reloader-turbopack.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ export async function createHotReloaderTurbopack(
254254
{
255255
persistentCaching: isPersistentCachingEnabled(opts.nextConfig),
256256
memoryLimit: opts.nextConfig.experimental?.turbopackMemoryLimit,
257+
isShortSession: false,
257258
}
258259
)
259260
backgroundLogCompilationEvents(project, {

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

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,18 @@ const COMPACT_CONFIG: CompactConfig = CompactConfig {
3030
pub struct TurboKeyValueDatabase {
3131
db: Arc<TurboPersistence>,
3232
compact_join_handle: Mutex<Option<JoinHandle<Result<()>>>>,
33+
is_ci: bool,
34+
is_short_session: bool,
3335
}
3436

3537
impl TurboKeyValueDatabase {
36-
pub fn new(versioned_path: PathBuf) -> Result<Self> {
38+
pub fn new(versioned_path: PathBuf, is_ci: bool, is_short_session: bool) -> Result<Self> {
3739
let db = Arc::new(TurboPersistence::open(versioned_path)?);
3840
let mut this = Self {
3941
db: db.clone(),
4042
compact_join_handle: Mutex::new(None),
43+
is_ci,
44+
is_short_session,
4145
};
4246
// start compaction in background if the database is not empty
4347
if !db.is_empty() {
@@ -98,8 +102,8 @@ impl KeyValueDatabase for TurboKeyValueDatabase {
98102
Ok(WriteBatch::concurrent(TurboWriteBatch {
99103
batch: self.db.write_batch()?,
100104
db: &self.db,
101-
compact_join_handle: &self.compact_join_handle,
102-
initial_write: self.db.is_empty(),
105+
compact_join_handle: (!self.is_short_session && !self.db.is_empty())
106+
.then_some(&self.compact_join_handle),
103107
}))
104108
}
105109

@@ -110,6 +114,16 @@ impl KeyValueDatabase for TurboKeyValueDatabase {
110114
if let Some(join_handle) = self.compact_join_handle.lock().take() {
111115
join_handle.join().unwrap()?;
112116
}
117+
// Compact the database on shutdown
118+
self.db.compact(&CompactConfig {
119+
max_merge_segment_count: if self.is_ci {
120+
// Fully compact in CI to reduce cache size
121+
usize::MAX
122+
} else {
123+
available_parallelism().map_or(4, |c| max(4, c.get()))
124+
},
125+
..COMPACT_CONFIG
126+
})?;
113127
// Shutdown the database
114128
self.db.shutdown()
115129
}
@@ -118,8 +132,7 @@ impl KeyValueDatabase for TurboKeyValueDatabase {
118132
pub struct TurboWriteBatch<'a> {
119133
batch: turbo_persistence::WriteBatch<WriteBuffer<'static>, 5>,
120134
db: &'a Arc<TurboPersistence>,
121-
compact_join_handle: &'a Mutex<Option<JoinHandle<Result<()>>>>,
122-
initial_write: bool,
135+
compact_join_handle: Option<&'a Mutex<Option<JoinHandle<Result<()>>>>>,
123136
}
124137

125138
impl<'a> BaseWriteBatch<'a> for TurboWriteBatch<'a> {
@@ -140,7 +153,7 @@ impl<'a> BaseWriteBatch<'a> for TurboWriteBatch<'a> {
140153
// Commit the write batch
141154
self.db.commit_write_batch(self.batch)?;
142155

143-
if !self.initial_write {
156+
if let Some(compact_join_handle) = self.compact_join_handle {
144157
// Start a new compaction in the background
145158
let db = self.db.clone();
146159
let handle = spawn(move || {
@@ -150,7 +163,7 @@ impl<'a> BaseWriteBatch<'a> for TurboWriteBatch<'a> {
150163
..COMPACT_CONFIG
151164
})
152165
});
153-
self.compact_join_handle.lock().replace(handle);
166+
compact_join_handle.lock().replace(handle);
154167
}
155168

156169
Ok(())

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,13 @@ pub fn turbo_backing_storage(
8383
base_path: &Path,
8484
version_info: &GitVersionInfo,
8585
is_ci: bool,
86+
is_short_session: bool,
8687
) -> Result<(TurboBackingStorage, StartupCacheState)> {
8788
KeyValueDatabaseBackingStorage::open_versioned_on_disk(
8889
base_path.to_owned(),
8990
version_info,
9091
is_ci,
91-
TurboKeyValueDatabase::new,
92+
|path| TurboKeyValueDatabase::new(path, is_ci, is_short_session),
9293
)
9394
}
9495

@@ -111,13 +112,14 @@ pub fn default_backing_storage(
111112
path: &Path,
112113
version_info: &GitVersionInfo,
113114
is_ci: bool,
115+
is_short_session: bool,
114116
) -> Result<(DefaultBackingStorage, StartupCacheState)> {
115117
#[cfg(feature = "lmdb")]
116118
{
117119
lmdb_backing_storage(path, version_info, is_ci)
118120
}
119121
#[cfg(not(feature = "lmdb"))]
120122
{
121-
turbo_backing_storage(path, version_info, is_ci)
123+
turbo_backing_storage(path, version_info, is_ci, is_short_session)
122124
}
123125
}

turbopack/crates/turbo-tasks-backend/tests/test_config.trs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
describe: "test-unversioned",
1717
dirty: false,
1818
},
19-
false
19+
false,
20+
true,
2021
).unwrap().0
2122
)
2223
)

turbopack/crates/turbo-tasks-fetch/tests/test_config.trs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
describe: "test-unversioned",
1717
dirty: false,
1818
},
19-
false
19+
false,
20+
true,
2021
).unwrap().0
2122
)
2223
)

turbopack/crates/turbopack/tests/node-file-trace.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ fn node_file_trace_persistent(#[case] input: CaseInput) {
292292
dirty: false,
293293
},
294294
false,
295+
true,
295296
)
296297
.unwrap()
297298
.0,

0 commit comments

Comments
 (0)