fs: Don't treat watcher errors as reason to do rescans (#56165)
Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Closes https://github.com/zed-industries/zed/issues/56064 This behavior regressed in https://github.com/zed-industries/zed/pull/54481 Release Notes: - Fixed an issue where broken symlinks, permission errors, or other fs errors in watched directories could cause excessive CPU usage
This commit is contained in:
1 parent
9461725b7e
commit
47cce5ab24
1 file changed
+9
-36
@@ -87,19 +87,11 @@ impl Watcher for FsWatcher {
|
||||
let path: Arc<std::path::Path> = path.into();
|
||||
|
||||
let registration_path = path.clone();
|
||||
let registration_id = global_watcher().add(
|
||||
path.clone(),
|
||||
self.mode,
|
||||
move |result: Result<¬ify::Event, ¬ify::Error>| match result {
|
||||
Ok(event) => {
|
||||
log::trace!("watcher received event: {event:?}");
|
||||
push_notify_event(&tx, &pending_path_events, &root_path, path.as_ref(), event);
|
||||
}
|
||||
Err(error) => {
|
||||
push_notify_error(&tx, &pending_path_events, path.as_ref(), error);
|
||||
}
|
||||
},
|
||||
)?;
|
||||
let registration_id =
|
||||
global_watcher().add(path.clone(), self.mode, move |event: ¬ify::Event| {
|
||||
log::trace!("watcher received event: {event:?}");
|
||||
push_notify_event(&tx, &pending_path_events, &root_path, path.as_ref(), event);
|
||||
})?;
|
||||
|
||||
self.registrations
|
||||
.lock()
|
||||
@@ -176,23 +168,6 @@ fn push_notify_event(
|
||||
enqueue_path_events(tx, pending_path_events, path_events);
|
||||
}
|
||||
|
||||
fn push_notify_error(
|
||||
tx: &smol::channel::Sender<()>,
|
||||
pending_path_events: &Arc<Mutex<Vec<PathEvent>>>,
|
||||
watched_root: &Path,
|
||||
error: ¬ify::Error,
|
||||
) {
|
||||
log::warn!("watcher error for {watched_root:?}: {error}");
|
||||
enqueue_path_events(
|
||||
tx,
|
||||
pending_path_events,
|
||||
vec![PathEvent {
|
||||
path: watched_root.to_path_buf(),
|
||||
kind: Some(PathEventKind::Rescan),
|
||||
}],
|
||||
);
|
||||
}
|
||||
|
||||
fn coalesce_pending_rescans(pending_paths: &mut Vec<PathEvent>, path_events: &mut Vec<PathEvent>) {
|
||||
if !path_events
|
||||
.iter()
|
||||
@@ -247,7 +222,7 @@ fn is_covered_rescan(kind: Option<PathEventKind>, path: &Path, ancestor: &Path)
|
||||
pub struct WatcherRegistrationId(u32);
|
||||
|
||||
struct WatcherRegistrationState {
|
||||
callback: Arc<dyn for<'a> Fn(Result<&'a notify::Event, &'a notify::Error>) + Send + Sync>,
|
||||
callback: Arc<dyn Fn(¬ify::Event) + Send + Sync>,
|
||||
path: Arc<std::path::Path>,
|
||||
mode: WatcherMode,
|
||||
}
|
||||
@@ -283,7 +258,7 @@ impl GlobalWatcher {
|
||||
&self,
|
||||
path: Arc<std::path::Path>,
|
||||
mode: WatcherMode,
|
||||
cb: impl for<'a> Fn(Result<&'a notify::Event, &'a notify::Error>) + Send + Sync + 'static,
|
||||
cb: impl Fn(¬ify::Event) + Send + Sync + 'static,
|
||||
) -> anyhow::Result<WatcherRegistrationId> {
|
||||
let mut state = self.state.lock();
|
||||
let registrations_for_mode = state.path_registrations(mode);
|
||||
@@ -483,13 +458,11 @@ fn handle_event(mode: WatcherMode, event: Result<notify::Event, notify::Error>)
|
||||
match event {
|
||||
Ok(event) => {
|
||||
for callback in callbacks {
|
||||
callback(Ok(&event));
|
||||
callback(&event);
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
for callback in callbacks {
|
||||
callback(Err(&error));
|
||||
}
|
||||
log::warn!("watcher error for {mode:?}: {error}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user