mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-22 21:41:37 +00:00
Add is_watch_enabled method to VFS and enhance prefetch cache tests
- Introduced `is_watch_enabled` method to check the status of automatic file watching in the VFS. - Added a new test for prefetch cache to validate metadata retrieval and error handling for walked roots and external paths. - Updated the `watch` method in `StdBackend` for cleaner logic. - Enhanced the `dir_init` field in `PrefetchCache` to store resolved init-file information for directories, improving prefetch operations.
This commit is contained in:
parent
8b18dc451a
commit
5275d45adc
6 changed files with 91 additions and 9 deletions
|
|
@ -419,6 +419,11 @@ impl Vfs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether automatic file watching is currently enabled.
|
||||||
|
pub fn is_watch_enabled(&self) -> bool {
|
||||||
|
self.inner.lock().unwrap().watch_enabled
|
||||||
|
}
|
||||||
|
|
||||||
/// Turns automatic file watching on or off. Enabled by default.
|
/// Turns automatic file watching on or off. Enabled by default.
|
||||||
///
|
///
|
||||||
/// Turning off file watching may be useful for single-use cases, especially
|
/// Turning off file watching may be useful for single-use cases, especially
|
||||||
|
|
@ -1008,6 +1013,63 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn prefetch_cache_walked_roots_fast_reject() {
|
||||||
|
let mut imfs = InMemoryFs::new();
|
||||||
|
imfs.load_snapshot(
|
||||||
|
"/root",
|
||||||
|
VfsSnapshot::dir(HashMap::from([
|
||||||
|
("known.txt", VfsSnapshot::file("hello")),
|
||||||
|
(
|
||||||
|
"subdir",
|
||||||
|
VfsSnapshot::dir(HashMap::from([("nested.txt", VfsSnapshot::file("world"))])),
|
||||||
|
),
|
||||||
|
])),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
imfs.load_snapshot("/outside/other.txt", VfsSnapshot::file("external"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let vfs = Vfs::new(imfs);
|
||||||
|
let mut is_file = HashMap::new();
|
||||||
|
is_file.insert(PathBuf::from("/root"), false);
|
||||||
|
is_file.insert(PathBuf::from("/root/known.txt"), true);
|
||||||
|
is_file.insert(PathBuf::from("/root/subdir"), false);
|
||||||
|
|
||||||
|
vfs.set_prefetch_cache(PrefetchCache {
|
||||||
|
files: HashMap::new(),
|
||||||
|
is_file,
|
||||||
|
children: HashMap::new(),
|
||||||
|
dir_init: HashMap::new(),
|
||||||
|
walked_roots: vec![PathBuf::from("/root")],
|
||||||
|
});
|
||||||
|
|
||||||
|
let known = vfs.metadata("/root/known.txt").unwrap();
|
||||||
|
assert!(
|
||||||
|
known.is_file(),
|
||||||
|
"cached entry should return correct metadata"
|
||||||
|
);
|
||||||
|
|
||||||
|
let subdir = vfs.metadata("/root/subdir").unwrap();
|
||||||
|
assert!(
|
||||||
|
subdir.is_dir(),
|
||||||
|
"cached directory should return correct metadata"
|
||||||
|
);
|
||||||
|
|
||||||
|
let missing = vfs.metadata("/root/subdir/nested.txt");
|
||||||
|
assert!(
|
||||||
|
missing.is_err(),
|
||||||
|
"path under walked root but not in cache should return NotFound"
|
||||||
|
);
|
||||||
|
assert_eq!(missing.unwrap_err().kind(), io::ErrorKind::NotFound);
|
||||||
|
|
||||||
|
let outside = vfs.metadata("/outside/other.txt").unwrap();
|
||||||
|
assert!(
|
||||||
|
outside.is_file(),
|
||||||
|
"path outside walked roots should fall through to backend"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prefetch_cache_read_after_write_ignores_cache() {
|
fn prefetch_cache_read_after_write_ignores_cache() {
|
||||||
let mut imfs = InMemoryFs::new();
|
let mut imfs = InMemoryFs::new();
|
||||||
|
|
|
||||||
|
|
@ -331,13 +331,9 @@ impl VfsBackend for StdBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn watch(&mut self, path: &Path, recursive: bool) -> io::Result<()> {
|
fn watch(&mut self, path: &Path, recursive: bool) -> io::Result<()> {
|
||||||
if self.watches.contains(path) {
|
if self.watches.contains(path) && (!recursive || self.recursive_watches.contains(path)) {
|
||||||
if !recursive || self.recursive_watches.contains(path) {
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
// Upgrade: path was watched non-recursively, now needs recursive.
|
|
||||||
// Fall through to re-issue the watch with RecursiveMode::Recursive.
|
|
||||||
}
|
|
||||||
if path
|
if path
|
||||||
.ancestors()
|
.ancestors()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,6 @@ pub use snapshot::{
|
||||||
InstanceContext, InstanceMetadata, InstanceSnapshot, InstanceWithMeta, InstanceWithMetaMut,
|
InstanceContext, InstanceMetadata, InstanceSnapshot, InstanceWithMeta, InstanceWithMetaMut,
|
||||||
RojoDescendants, RojoTree,
|
RojoDescendants, RojoTree,
|
||||||
};
|
};
|
||||||
pub use snapshot_middleware::{snapshot_from_vfs, Middleware, ScriptType};
|
pub use snapshot_middleware::{snapshot_from_vfs, Middleware, ScriptType, INIT_FILE_PRIORITY};
|
||||||
pub use syncback::{syncback_loop, FsSnapshot, SyncbackData, SyncbackResult, SyncbackSnapshot};
|
pub use syncback::{syncback_loop, FsSnapshot, SyncbackData, SyncbackResult, SyncbackSnapshot};
|
||||||
pub use web::interface as web_api;
|
pub use web::interface as web_api;
|
||||||
|
|
|
||||||
|
|
@ -349,9 +349,10 @@ impl ServeSession {
|
||||||
|
|
||||||
let snap_start = Instant::now();
|
let snap_start = Instant::now();
|
||||||
log::trace!("Generating snapshot of instances from VFS");
|
log::trace!("Generating snapshot of instances from VFS");
|
||||||
|
let was_watch_enabled = vfs.is_watch_enabled();
|
||||||
vfs.set_watch_enabled(false);
|
vfs.set_watch_enabled(false);
|
||||||
let snapshot = snapshot_from_vfs(&instance_context, vfs, start_path)?;
|
let snapshot = snapshot_from_vfs(&instance_context, vfs, start_path)?;
|
||||||
vfs.set_watch_enabled(true);
|
vfs.set_watch_enabled(was_watch_enabled);
|
||||||
log::debug!("Snapshot built in {:.1?}", snap_start.elapsed());
|
log::debug!("Snapshot built in {:.1?}", snap_start.elapsed());
|
||||||
|
|
||||||
vfs.clear_prefetch_cache();
|
vfs.clear_prefetch_cache();
|
||||||
|
|
|
||||||
|
|
@ -544,6 +544,12 @@ mod test {
|
||||||
"DEFAULT_PROJECT_NAMES entry {project_name:?} missing from INIT_FILE_PRIORITY"
|
"DEFAULT_PROJECT_NAMES entry {project_name:?} missing from INIT_FILE_PRIORITY"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
for &name in &priority_names {
|
||||||
|
assert!(
|
||||||
|
DEFAULT_PROJECT_NAMES.contains(&name),
|
||||||
|
"INIT_FILE_PRIORITY has Project entry {name:?} not in DEFAULT_PROJECT_NAMES"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -263,12 +263,29 @@ fn parallel_snapshot_with_prefetch_cache() {
|
||||||
children.sort_by(|a, b| a.file_name().cmp(&b.file_name()));
|
children.sort_by(|a, b| a.file_name().cmp(&b.file_name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut dir_init: HashMap<std::path::PathBuf, Option<(String, std::path::PathBuf)>> =
|
||||||
|
HashMap::new();
|
||||||
|
for (dir_path, child_paths) in &children_map {
|
||||||
|
let child_names: std::collections::HashSet<&str> = child_paths
|
||||||
|
.iter()
|
||||||
|
.filter_map(|p| p.file_name().and_then(|n| n.to_str()))
|
||||||
|
.collect();
|
||||||
|
let mut found = None;
|
||||||
|
for &(_, init_name) in librojo::INIT_FILE_PRIORITY {
|
||||||
|
if child_names.contains(init_name) {
|
||||||
|
found = Some((init_name.to_string(), dir_path.join(init_name)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir_init.insert(dir_path.clone(), found);
|
||||||
|
}
|
||||||
|
|
||||||
let vfs_cached = memofs::Vfs::new_default();
|
let vfs_cached = memofs::Vfs::new_default();
|
||||||
vfs_cached.set_prefetch_cache(memofs::PrefetchCache {
|
vfs_cached.set_prefetch_cache(memofs::PrefetchCache {
|
||||||
files,
|
files,
|
||||||
is_file,
|
is_file,
|
||||||
children: children_map,
|
children: children_map,
|
||||||
dir_init: std::collections::HashMap::new(),
|
dir_init,
|
||||||
walked_roots: Vec::new(),
|
walked_roots: Vec::new(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue