Skip to content

Commit 121cfa8

Browse files
committed
cache directory creation
1 parent e5164cd commit 121cfa8

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(),
@@ -743,20 +770,13 @@ impl FileSystem for DiskFileSystem {
743770
let create_directory = compare == FileComparison::Create;
744771
if create_directory {
745772
if let Some(parent) = full_path.parent() {
746-
retry_blocking(parent, |p| std::fs::create_dir_all(p))
747-
.concurrency_limited(&inner.semaphore)
748-
.instrument(tracing::info_span!(
749-
"create directory",
750-
path = display(parent.display())
751-
))
752-
.await
753-
.with_context(|| {
754-
format!(
755-
"failed to create directory {} for write to {}",
756-
parent.display(),
757-
full_path.display()
758-
)
759-
})?;
773+
inner.create_directory(parent).await.with_context(|| {
774+
format!(
775+
"failed to create directory {} for write to {}",
776+
parent.display(),
777+
full_path.display()
778+
)
779+
})?;
760780
}
761781
}
762782
let full_path_to_write = full_path.clone();
@@ -879,20 +899,13 @@ impl FileSystem for DiskFileSystem {
879899
let create_directory = old_content.is_none();
880900
if create_directory {
881901
if let Some(parent) = full_path.parent() {
882-
retry_blocking(parent, |path| std::fs::create_dir_all(path))
883-
.concurrency_limited(&inner.semaphore)
884-
.instrument(tracing::info_span!(
885-
"create directory",
886-
path = display(parent.display())
887-
))
888-
.await
889-
.with_context(|| {
890-
format!(
891-
"failed to create directory {} for write to {}",
892-
parent.display(),
893-
full_path.display()
894-
)
895-
})?;
902+
inner.create_directory(parent).await.with_context(|| {
903+
format!(
904+
"failed to create directory {} for write link to {}",
905+
parent.display(),
906+
full_path.display()
907+
)
908+
})?;
896909
}
897910
}
898911

0 commit comments

Comments
 (0)