mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
perf: detach the watch registration from the main thread (#2224)
This commit is contained in:
parent
7bd79521da
commit
ed3c9c4f3c
1 changed files with 35 additions and 17 deletions
|
|
@ -96,28 +96,17 @@ impl Watcher {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fan_in(mut rx: watch::Receiver<HashSet<Url>>, mut watcher: impl notify::Watcher) {
|
async fn fan_in(
|
||||||
|
mut rx: watch::Receiver<HashSet<Url>>,
|
||||||
|
mut watcher: impl notify::Watcher + Send + 'static,
|
||||||
|
) {
|
||||||
loop {
|
loop {
|
||||||
let (mut to_unwatch, mut to_watch): (HashSet<_>, HashSet<_>) = {
|
let (to_unwatch, to_watch): (HashSet<_>, HashSet<_>) = {
|
||||||
let (new, old) = (&*rx.borrow_and_update(), &*WATCHED.read());
|
let (new, old) = (&*rx.borrow_and_update(), &*WATCHED.read());
|
||||||
(old.difference(new).cloned().collect(), new.difference(old).cloned().collect())
|
(old.difference(new).cloned().collect(), new.difference(old).cloned().collect())
|
||||||
};
|
};
|
||||||
|
|
||||||
to_unwatch.retain(|u| match watcher.unwatch(u) {
|
watcher = Self::sync_watched(watcher, to_unwatch, to_watch).await;
|
||||||
Ok(_) => true,
|
|
||||||
Err(e) if matches!(e.kind, notify::ErrorKind::WatchNotFound) => true,
|
|
||||||
Err(e) => {
|
|
||||||
error!("Unwatch failed: {e:?}");
|
|
||||||
false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
to_watch.retain(|u| watcher.watch(u, RecursiveMode::NonRecursive).is_ok());
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut watched = WATCHED.write();
|
|
||||||
watched.retain(|u| !to_unwatch.contains(u));
|
|
||||||
watched.extend(to_watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !rx.has_changed().unwrap_or(false) {
|
if !rx.has_changed().unwrap_or(false) {
|
||||||
Self::sync_linked().await;
|
Self::sync_linked().await;
|
||||||
|
|
@ -173,6 +162,35 @@ impl Watcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn sync_watched<W>(mut watcher: W, to_unwatch: HashSet<Url>, to_watch: HashSet<Url>) -> W
|
||||||
|
where
|
||||||
|
W: notify::Watcher + Send + 'static,
|
||||||
|
{
|
||||||
|
use notify::ErrorKind::WatchNotFound;
|
||||||
|
|
||||||
|
if to_unwatch.is_empty() && to_watch.is_empty() {
|
||||||
|
return watcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokio::task::spawn_blocking(move || {
|
||||||
|
for u in to_unwatch {
|
||||||
|
match watcher.unwatch(&u) {
|
||||||
|
Ok(()) => _ = WATCHED.write().remove(&u),
|
||||||
|
Err(e) if matches!(e.kind, WatchNotFound) => _ = WATCHED.write().remove(&u),
|
||||||
|
Err(e) => error!("Unwatch failed: {e:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for u in to_watch {
|
||||||
|
if watcher.watch(&u, RecursiveMode::NonRecursive).is_ok() {
|
||||||
|
WATCHED.write().insert(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
watcher
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
async fn sync_linked() {
|
async fn sync_linked() {
|
||||||
let mut new = WATCHED.read().clone();
|
let mut new = WATCHED.read().clone();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue