Skip to content

Commit dbfa684

Browse files
committed
cache directory creation
1 parent 158ba69 commit dbfa684

File tree

1 file changed

+41
-28
lines changed
  • turbopack/crates/turbo-tasks-fs/src

1 file changed

+41
-28
lines changed

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

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use std::{
3939
use anyhow::{anyhow, bail, Context, Result};
4040
use auto_hash_map::{AutoMap, AutoSet};
4141
use bitflags::bitflags;
42+
use dashmap::DashSet;
4243
use dunce::simplified;
4344
use glob::Glob;
4445
use indexmap::IndexSet;
@@ -227,6 +228,10 @@ struct DiskFileSystemInner {
227228
#[turbo_tasks(debug_ignore, trace_ignore)]
228229
#[serde(skip)]
229230
invalidation_lock: RwLock<()>,
231+
/// A cache of already created directories to avoid creating them multiple times.
232+
#[turbo_tasks(debug_ignore, trace_ignore)]
233+
#[serde(skip)]
234+
created_directories: DashSet<PathBuf>,
230235
/// Semaphore to limit the maximum number of concurrent file operations.
231236
#[turbo_tasks(debug_ignore, trace_ignore)]
232237
#[serde(skip, default = "create_semaphore")]
@@ -394,6 +399,27 @@ impl DiskFileSystemInner {
394399

395400
Ok(())
396401
}
402+
403+
async fn create_directory(self: &Arc<Self>, directory: &Path) -> Result<()> {
404+
if !self.created_directories.contains(directory) {
405+
let func = {
406+
let inner = self.clone();
407+
move |p: &Path| -> io::Result<()> {
408+
std::fs::create_dir_all(p)?;
409+
inner.created_directories.insert(p.to_path_buf());
410+
Ok(())
411+
}
412+
};
413+
retry_blocking(directory, func)
414+
.concurrency_limited(&self.semaphore)
415+
.instrument(tracing::info_span!(
416+
"create directory",
417+
path = display(directory.display())
418+
))
419+
.await?;
420+
}
421+
Ok(())
422+
}
397423
}
398424

399425
#[turbo_tasks::value(cell = "new", eq = "manual")]
@@ -500,6 +526,7 @@ impl DiskFileSystem {
500526
invalidation_lock: Default::default(),
501527
invalidator_map: InvalidatorMap::new(),
502528
dir_invalidator_map: InvalidatorMap::new(),
529+
created_directories: Default::default(),
503530
semaphore: create_semaphore(),
504531
watcher: DiskWatcher::new(
505532
ignored_subpaths.into_iter().map(PathBuf::from).collect(),
@@ -744,20 +771,13 @@ impl FileSystem for DiskFileSystem {
744771
let create_directory = compare == FileComparison::Create;
745772
if create_directory {
746773
if let Some(parent) = full_path.parent() {
747-
retry_blocking(parent, |p| std::fs::create_dir_all(p))
748-
.concurrency_limited(&inner.semaphore)
749-
.instrument(tracing::info_span!(
750-
"create directory",
751-
path = display(parent.display())
752-
))
753-
.await
754-
.with_context(|| {
755-
format!(
756-
"failed to create directory {} for write to {}",
757-
parent.display(),
758-
full_path.display()
759-
)
760-
})?;
774+
inner.create_directory(parent).await.with_context(|| {
775+
format!(
776+
"failed to create directory {} for write to {}",
777+
parent.display(),
778+
full_path.display()
779+
)
780+
})?;
761781
}
762782
}
763783
let full_path_to_write = full_path.clone();
@@ -881,20 +901,13 @@ impl FileSystem for DiskFileSystem {
881901
let create_directory = old_content.is_none();
882902
if create_directory {
883903
if let Some(parent) = full_path.parent() {
884-
retry_blocking(parent, |path| std::fs::create_dir_all(path))
885-
.concurrency_limited(&inner.semaphore)
886-
.instrument(tracing::info_span!(
887-
"create directory",
888-
path = display(parent.display())
889-
))
890-
.await
891-
.with_context(|| {
892-
format!(
893-
"failed to create directory {} for write to {}",
894-
parent.display(),
895-
full_path.display()
896-
)
897-
})?;
904+
inner.create_directory(parent).await.with_context(|| {
905+
format!(
906+
"failed to create directory {} for write link to {}",
907+
parent.display(),
908+
full_path.display()
909+
)
910+
})?;
898911
}
899912
}
900913

0 commit comments

Comments
 (0)