Rework Worktree::scan_complete
to use a watch
This commit is contained in:
parent
a4c1fe5a0b
commit
d11d5483b6
1 changed files with 19 additions and 36 deletions
|
@ -6,20 +6,21 @@ use crate::{
|
||||||
sum_tree::{self, Edit, SumTree},
|
sum_tree::{self, Edit, SumTree},
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use futures_core::future::BoxFuture;
|
|
||||||
pub use fuzzy::match_paths;
|
|
||||||
use fuzzy::PathEntry;
|
use fuzzy::PathEntry;
|
||||||
|
pub use fuzzy::{match_paths, PathMatch};
|
||||||
use gpui::{scoped_pool, AppContext, Entity, ModelContext, ModelHandle, Task};
|
use gpui::{scoped_pool, AppContext, Entity, ModelContext, ModelHandle, Task};
|
||||||
use ignore::dir::{Ignore, IgnoreBuilder};
|
use ignore::dir::{Ignore, IgnoreBuilder};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use postage::{oneshot, prelude::Stream, sink::Sink};
|
use postage::{
|
||||||
|
prelude::{Sink, Stream},
|
||||||
|
watch,
|
||||||
|
};
|
||||||
use smol::{channel::Sender, Timer};
|
use smol::{channel::Sender, Timer};
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
fmt, fs,
|
fmt, fs,
|
||||||
future::Future,
|
future::Future,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
mem,
|
|
||||||
ops::{AddAssign, Deref},
|
ops::{AddAssign, Deref},
|
||||||
os::unix::fs::MetadataExt,
|
os::unix::fs::MetadataExt,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
@ -27,20 +28,17 @@ use std::{
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use fuzzy::PathMatch;
|
#[derive(Clone, Debug)]
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum ScanState {
|
enum ScanState {
|
||||||
Idle,
|
Idle,
|
||||||
Scanning,
|
Scanning,
|
||||||
Err(io::Error),
|
Err(Arc<io::Error>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Worktree {
|
pub struct Worktree {
|
||||||
snapshot: Snapshot,
|
snapshot: Snapshot,
|
||||||
scanner: Arc<BackgroundScanner>,
|
scanner: Arc<BackgroundScanner>,
|
||||||
scan_listeners: Mutex<Vec<postage::oneshot::Sender<()>>>,
|
scan_state: (watch::Sender<ScanState>, watch::Receiver<ScanState>),
|
||||||
scan_state: ScanState,
|
|
||||||
poll_scheduled: bool,
|
poll_scheduled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +61,7 @@ impl Worktree {
|
||||||
let tree = Self {
|
let tree = Self {
|
||||||
snapshot,
|
snapshot,
|
||||||
scanner,
|
scanner,
|
||||||
scan_listeners: Default::default(),
|
scan_state: watch::channel_with(ScanState::Scanning),
|
||||||
scan_state: ScanState::Scanning,
|
|
||||||
poll_scheduled: false,
|
poll_scheduled: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,20 +74,18 @@ impl Worktree {
|
||||||
tree
|
tree
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scan_complete(&self) -> BoxFuture<'static, ()> {
|
pub fn scan_complete(&self) -> impl Future<Output = ()> {
|
||||||
if self.is_scanning() {
|
let mut scan_state_rx = self.scan_state.1.clone();
|
||||||
let (tx, mut rx) = oneshot::channel::<()>();
|
async move {
|
||||||
self.scan_listeners.lock().push(tx);
|
let mut next_scan_state = Some(scan_state_rx.borrow().clone());
|
||||||
Box::pin(async move {
|
while let Some(ScanState::Scanning) = next_scan_state {
|
||||||
rx.recv().await;
|
next_scan_state = scan_state_rx.recv().await;
|
||||||
})
|
}
|
||||||
} else {
|
|
||||||
Box::pin(async {})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn observe_scan_state(&mut self, scan_state: ScanState, ctx: &mut ModelContext<Self>) {
|
fn observe_scan_state(&mut self, scan_state: ScanState, ctx: &mut ModelContext<Self>) {
|
||||||
self.scan_state = scan_state;
|
let _ = self.scan_state.0.blocking_send(scan_state);
|
||||||
self.poll_entries(ctx);
|
self.poll_entries(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,23 +100,11 @@ impl Worktree {
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
self.poll_scheduled = true;
|
self.poll_scheduled = true;
|
||||||
} else {
|
|
||||||
let mut listeners = Vec::new();
|
|
||||||
mem::swap(self.scan_listeners.lock().as_mut(), &mut listeners);
|
|
||||||
ctx.spawn(
|
|
||||||
async move {
|
|
||||||
for mut tx in listeners {
|
|
||||||
tx.send(()).await.ok();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|_, _, _| {},
|
|
||||||
)
|
|
||||||
.detach();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_scanning(&self) -> bool {
|
fn is_scanning(&self) -> bool {
|
||||||
if let ScanState::Scanning = self.scan_state {
|
if let ScanState::Scanning = *self.scan_state.1.borrow() {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -554,7 +537,7 @@ impl BackgroundScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(err) = self.scan_dirs() {
|
if let Err(err) = self.scan_dirs() {
|
||||||
if smol::block_on(self.notify.send(ScanState::Err(err))).is_err() {
|
if smol::block_on(self.notify.send(ScanState::Err(Arc::new(err)))).is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue