mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-25 04:54:07 +00:00
Refactor VFS watch logic for macOS and Linux/Windows compatibility
- Enhanced the VFS watch setup in ServeSession to differentiate between macOS and other platforms, ensuring proper handling of file and directory watches. - Improved clarity by restructuring the logic for watching paths, addressing platform-specific requirements and optimizing resource usage. - Maintained non-recursive watching for ignored directories while ensuring all relevant files are monitored effectively.
This commit is contained in:
parent
c19b249657
commit
4b38c070fb
1 changed files with 39 additions and 28 deletions
|
|
@ -384,17 +384,20 @@ impl ServeSession {
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
let watch_start = Instant::now();
|
let watch_start = Instant::now();
|
||||||
// Walk each $path root, skipping directories that match
|
let mut watch_count: usize = 0;
|
||||||
// globIgnorePaths, and watch each non-ignored directory
|
|
||||||
// individually (non-recursive). This avoids creating kqueue
|
if cfg!(target_os = "macos") {
|
||||||
// FDs for ignored subtrees on macOS.
|
// macOS kqueue: one FD per watched path. Walk each $path
|
||||||
|
// root, skip globIgnorePaths subtrees, and watch every
|
||||||
|
// non-ignored file and directory non-recursively. File
|
||||||
|
// watches are required because kqueue directory watches
|
||||||
|
// only fire for structural changes, not child content edits.
|
||||||
let passes_ignore = |entry: &walkdir::DirEntry| -> bool {
|
let passes_ignore = |entry: &walkdir::DirEntry| -> bool {
|
||||||
watch_ignore_rules
|
watch_ignore_rules
|
||||||
.iter()
|
.iter()
|
||||||
.all(|rule: &PathIgnoreRule| rule.passes(entry.path()))
|
.all(|rule: &PathIgnoreRule| rule.passes(entry.path()))
|
||||||
};
|
};
|
||||||
vfs.set_watch_recursive(false);
|
vfs.set_watch_recursive(false);
|
||||||
let mut watch_count: usize = 0;
|
|
||||||
for root in &path_roots {
|
for root in &path_roots {
|
||||||
for entry in WalkDir::new(root)
|
for entry in WalkDir::new(root)
|
||||||
.follow_links(true)
|
.follow_links(true)
|
||||||
|
|
@ -402,20 +405,28 @@ impl ServeSession {
|
||||||
.filter_entry(&passes_ignore)
|
.filter_entry(&passes_ignore)
|
||||||
.flatten()
|
.flatten()
|
||||||
{
|
{
|
||||||
// Watch both files and directories. On macOS kqueue,
|
|
||||||
// file watches are required because directory watches
|
|
||||||
// only fire for structural changes. On Linux/Windows,
|
|
||||||
// file watches prevent a debouncer race where read_raw's
|
|
||||||
// auto-registered file watch conflicts with the directory
|
|
||||||
// watch during rename-overwrite (atomic save pattern).
|
|
||||||
let _ = vfs.watch(entry.path());
|
let _ = vfs.watch(entry.path());
|
||||||
watch_count += 1;
|
watch_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Watch project folder non-recursively for project file edits.
|
|
||||||
let _ = vfs.watch(&project_folder);
|
let _ = vfs.watch(&project_folder);
|
||||||
watch_count += 1;
|
watch_count += 1;
|
||||||
vfs.set_watch_recursive(true);
|
vfs.set_watch_recursive(true);
|
||||||
|
} else {
|
||||||
|
// Linux/Windows: inotify uses a single FD for all watches,
|
||||||
|
// RDCW uses one handle per directory. Recursive watches are
|
||||||
|
// cheap and directory watches already cover child file
|
||||||
|
// events. globIgnorePaths filtering is handled by the
|
||||||
|
// change processor's event filter.
|
||||||
|
for root in &path_roots {
|
||||||
|
let _ = vfs.watch(root);
|
||||||
|
watch_count += 1;
|
||||||
|
}
|
||||||
|
vfs.set_watch_recursive(false);
|
||||||
|
let _ = vfs.watch(&project_folder);
|
||||||
|
vfs.set_watch_recursive(true);
|
||||||
|
watch_count += 1;
|
||||||
|
}
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Set up {} watches in {:.1?}",
|
"Set up {} watches in {:.1?}",
|
||||||
watch_count,
|
watch_count,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue