Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions crates/next-api/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,15 @@ impl ProjectContainer {
.await?;
} else {
project_fs.invalidate_with_reason(|path| invalidation::Initialize {
path: RcStr::from(path),
// this path is just used for display purposes
path: RcStr::from(path.to_string_lossy()),
});
}
let output_fs = output_fs_operation(project)
.read_strongly_consistent()
.await?;
output_fs.invalidate_with_reason(|path| invalidation::Initialize {
path: RcStr::from(path),
path: RcStr::from(path.to_string_lossy()),
});
Ok(())
}
Expand Down Expand Up @@ -421,13 +422,14 @@ impl ProjectContainer {
.await?;
} else {
project_fs.invalidate_with_reason(|path| invalidation::Initialize {
path: RcStr::from(path),
// this path is just used for display purposes
path: RcStr::from(path.to_string_lossy()),
});
}
}
if !ReadRef::ptr_eq(&prev_output_fs, &output_fs) {
prev_output_fs.invalidate_with_reason(|path| invalidation::Initialize {
path: RcStr::from(path),
path: RcStr::from(path.to_string_lossy()),
});
}

Expand Down
21 changes: 16 additions & 5 deletions turbopack/crates/turbo-tasks-fs/src/invalidator_map.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::sync::{LockResult, Mutex, MutexGuard};
use std::{
path::PathBuf,
sync::{LockResult, Mutex, MutexGuard},
};

use concurrent_queue::ConcurrentQueue;
use rustc_hash::FxHashMap;
Expand All @@ -13,10 +16,10 @@ pub enum WriteContent {
Link(ReadRef<LinkContent>),
}

type InnerMap = FxHashMap<String, FxHashMap<Invalidator, Option<WriteContent>>>;
type InnerMap = FxHashMap<PathBuf, FxHashMap<Invalidator, Option<WriteContent>>>;

pub struct InvalidatorMap {
queue: ConcurrentQueue<(String, Invalidator, Option<WriteContent>)>,
queue: ConcurrentQueue<(PathBuf, Invalidator, Option<WriteContent>)>,
map: Mutex<InnerMap>,
}

Expand Down Expand Up @@ -44,7 +47,7 @@ impl InvalidatorMap {

pub fn insert(
&self,
key: String,
key: PathBuf,
invalidator: Invalidator,
write_content: Option<WriteContent>,
) {
Expand All @@ -66,7 +69,15 @@ impl Serialize for InvalidatorMap {
where
S: serde::Serializer,
{
serializer.serialize_newtype_struct("InvalidatorMap", &*self.lock().unwrap())
// TODO: This stores absolute `PathBuf`s, which are machine-specific. This should
// normalize/denormalize paths relative to the disk filesystem root.
//
// Potential optimization: We invalidate all fs reads immediately upon resuming from a
// persisted cache, but we don't invalidate the fs writes. Those read invalidations trigger
// re-inserts into the `InvalidatorMap`. If we knew that certain invalidators were only
// needed for reads, we could potentially avoid serializing those paths entirely.
let inner: &InnerMap = &self.lock().unwrap();
serializer.serialize_newtype_struct("InvalidatorMap", inner)
}
}

Expand Down
34 changes: 16 additions & 18 deletions turbopack/crates/turbo-tasks-fs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ impl DiskFileSystemInner {
fn register_read_invalidator(&self, path: &Path) -> Result<()> {
let invalidator = turbo_tasks::get_invalidator();
self.invalidator_map
.insert(path_to_key(path), invalidator, None);
.insert(path.to_owned(), invalidator, None);
if let Some(non_recursive) = &self.watcher.non_recursive_state
&& let Some(dir) = path.parent()
{
Expand All @@ -273,7 +273,7 @@ impl DiskFileSystemInner {
write_content: WriteContent,
) -> Result<Vec<(Invalidator, Option<WriteContent>)>> {
let mut invalidator_map = self.invalidator_map.lock().unwrap();
let invalidators = invalidator_map.entry(path_to_key(path)).or_default();
let invalidators = invalidator_map.entry(path.to_owned()).or_default();
let old_invalidators = invalidators
.extract_if(|i, old_write_content| {
i == &invalidator
Expand All @@ -298,7 +298,7 @@ impl DiskFileSystemInner {
fn register_dir_invalidator(&self, path: &Path) -> Result<()> {
let invalidator = turbo_tasks::get_invalidator();
self.dir_invalidator_map
.insert(path_to_key(path), invalidator, None);
.insert(path.to_owned(), invalidator, None);
if let Some(non_recursive) = &self.watcher.non_recursive_state {
non_recursive.ensure_watching(&self.watcher, path, self.root_path())?;
}
Expand Down Expand Up @@ -333,7 +333,7 @@ impl DiskFileSystemInner {
/// Calls the given
fn invalidate_with_reason<R: InvalidationReason + Clone>(
&self,
reason: impl Fn(String) -> R + Sync,
reason: impl Fn(&Path) -> R + Sync,
) {
let _span = tracing::info_span!("invalidate filesystem", name = &*self.root).entered();
let span = tracing::Span::current();
Expand All @@ -345,7 +345,7 @@ impl DiskFileSystemInner {
.chain(dir_invalidator_map.into_par_iter())
.flat_map(|(path, invalidators)| {
let _span = span.clone().entered();
let reason_for_path = reason(path);
let reason_for_path = reason(&path);
invalidators
.into_par_iter()
.map(move |i| (reason_for_path.clone(), i))
Expand Down Expand Up @@ -449,7 +449,7 @@ impl DiskFileSystem {

pub fn invalidate_with_reason<R: InvalidationReason + Clone>(
&self,
reason: impl Fn(String) -> R + Sync,
reason: impl Fn(&Path) -> R + Sync,
) {
self.inner.invalidate_with_reason(reason);
}
Expand Down Expand Up @@ -504,10 +504,6 @@ fn format_absolute_fs_path(path: &Path, name: &str, root_path: &Path) -> Option<
}
}

pub fn path_to_key(path: impl AsRef<Path>) -> String {
path.as_ref().to_string_lossy().to_string()
}

#[turbo_tasks::value_impl]
impl DiskFileSystem {
/// Create a new instance of `DiskFileSystem`.
Expand Down Expand Up @@ -756,11 +752,12 @@ impl FileSystem for DiskFileSystem {
.await?;
if compare == FileComparison::Equal {
if !old_invalidators.is_empty() {
let key = path_to_key(&full_path);
for (invalidator, write_content) in old_invalidators {
inner
.invalidator_map
.insert(key.clone(), invalidator, write_content);
inner.invalidator_map.insert(
full_path.clone().into_owned(),
invalidator,
write_content,
);
}
}
return Ok(());
Expand Down Expand Up @@ -899,11 +896,12 @@ impl FileSystem for DiskFileSystem {
};
if is_equal {
if !old_invalidators.is_empty() {
let key = path_to_key(&full_path);
for (invalidator, write_content) in old_invalidators {
inner
.invalidator_map
.insert(key.clone(), invalidator, write_content);
inner.invalidator_map.insert(
full_path.clone().into_owned(),
invalidator,
write_content,
);
}
}
return Ok(());
Expand Down
17 changes: 8 additions & 9 deletions turbopack/crates/turbo-tasks-fs/src/watcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ use crate::{
DiskFileSystemInner, format_absolute_fs_path,
invalidation::{WatchChange, WatchStart},
invalidator_map::WriteContent,
path_to_key,
};

static WATCH_RECURSIVE_MODE: LazyLock<RecursiveMode> = LazyLock::new(|| {
Expand Down Expand Up @@ -279,7 +278,8 @@ impl DiskWatcher {
let _span = span.clone().entered();
let reason = WatchStart {
name: fs_inner.name.clone(),
path: path.into(),
// this path is just used for display purposes
path: RcStr::from(path.to_string_lossy()),
};
invalidators
.into_par_iter()
Expand Down Expand Up @@ -374,7 +374,8 @@ impl DiskWatcher {

if report_invalidation_reason {
inner.invalidate_with_reason(|path| InvalidateRescan {
path: RcStr::from(path),
// this path is just used for display purposes
path: RcStr::from(path.to_string_lossy()),
});
} else {
inner.invalidate();
Expand Down Expand Up @@ -601,12 +602,11 @@ fn invalidate(
fn invalidate_path(
inner: &DiskFileSystemInner,
report_invalidation_reason: bool,
invalidator_map: &mut FxHashMap<String, FxHashMap<Invalidator, Option<WriteContent>>>,
invalidator_map: &mut FxHashMap<PathBuf, FxHashMap<Invalidator, Option<WriteContent>>>,
paths: impl Iterator<Item = PathBuf>,
) {
for path in paths {
let key = path_to_key(&path);
if let Some(invalidators) = invalidator_map.remove(&key) {
if let Some(invalidators) = invalidator_map.remove(&path) {
invalidators
.into_iter()
.for_each(|(i, _)| invalidate(inner, report_invalidation_reason, &path, i));
Expand All @@ -617,12 +617,11 @@ fn invalidate_path(
fn invalidate_path_and_children_execute(
inner: &DiskFileSystemInner,
report_invalidation_reason: bool,
invalidator_map: &mut FxHashMap<String, FxHashMap<Invalidator, Option<WriteContent>>>,
invalidator_map: &mut FxHashMap<PathBuf, FxHashMap<Invalidator, Option<WriteContent>>>,
paths: impl Iterator<Item = PathBuf>,
) {
for path in paths {
let path_key = path_to_key(&path);
for (_, invalidators) in invalidator_map.extract_if(|key, _| key.starts_with(&path_key)) {
for (_, invalidators) in invalidator_map.extract_if(|key, _| key.starts_with(&path)) {
invalidators
.into_iter()
.for_each(|(i, _)| invalidate(inner, report_invalidation_reason, &path, i));
Expand Down