Upgrade to Notify 6 (#816)

This commit is contained in:
Jack T
2023-11-23 16:16:43 -08:00
committed by GitHub
parent 41994ec82e
commit b43b45be8f
5 changed files with 74 additions and 180 deletions

View File

@@ -1,25 +1,23 @@
use std::io;
use std::path::Path;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use crossbeam_channel::Receiver;
use notify::{DebouncedEvent, RecursiveMode, Watcher};
use notify::{Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
#[cfg(target_os = "macos")]
use notify::PollWatcher;
#[cfg(not(target_os = "macos"))]
use notify::{watcher, RecommendedWatcher};
use notify::{Config, PollWatcher};
#[cfg(target_os = "macos")]
use std::time::Duration;
use crate::{DirEntry, Metadata, ReadDir, VfsBackend, VfsEvent};
/// `VfsBackend` that uses `std::fs` and the `notify` crate.
pub struct StdBackend {
// We use PollWatcher on macos because using the KQueue watcher
// can cause some gnarly performance problems.
#[cfg(target_os = "macos")]
watcher: PollWatcher,
#[cfg(not(target_os = "macos"))]
watcher: RecommendedWatcher,
@@ -28,37 +26,39 @@ pub struct StdBackend {
impl StdBackend {
pub fn new() -> StdBackend {
let (notify_tx, notify_rx) = mpsc::channel();
#[cfg(target_os = "macos")]
let watcher = PollWatcher::new(notify_tx, Duration::from_millis(50)).unwrap();
#[cfg(not(target_os = "macos"))]
let watcher = watcher(notify_tx, Duration::from_millis(50)).unwrap();
let (tx, rx) = crossbeam_channel::unbounded();
thread::spawn(move || {
for event in notify_rx {
match event {
DebouncedEvent::Create(path) => {
tx.send(VfsEvent::Create(path))?;
let event_handler = move |res: Result<Event, _>| match res {
Ok(event) => match event.kind {
EventKind::Create(_) => {
for path in event.paths {
let _ = tx.send(VfsEvent::Create(path));
}
DebouncedEvent::Write(path) => {
tx.send(VfsEvent::Write(path))?;
}
DebouncedEvent::Remove(path) => {
tx.send(VfsEvent::Remove(path))?;
}
DebouncedEvent::Rename(from, to) => {
tx.send(VfsEvent::Remove(from))?;
tx.send(VfsEvent::Create(to))?;
}
_ => {}
}
}
EventKind::Modify(_) => {
for path in event.paths {
let _ = tx.send(VfsEvent::Write(path));
}
}
EventKind::Remove(_) => {
for path in event.paths {
let _ = tx.send(VfsEvent::Remove(path));
}
}
_ => {}
},
Err(e) => println!("watch error: {:?}", e),
};
Result::<(), crossbeam_channel::SendError<VfsEvent>>::Ok(())
});
#[cfg(not(target_os = "macos"))]
let watcher = notify::recommended_watcher(event_handler).unwrap();
#[cfg(target_os = "macos")]
let watcher = PollWatcher::new(
event_handler,
Config::default().with_poll_interval(Duration::from_millis(200)),
)
.unwrap();
Self {
watcher,