From 5fdbc38f460ba983e6edbd02d2d5c06f55a47d34 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 30 Jun 2022 15:46:31 -0700 Subject: [PATCH] Don't update worktrees' snapshots in the middle of processing fs events --- crates/project/src/worktree.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 8dee1c8261..e6af57bf5c 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -125,7 +125,10 @@ impl DerefMut for LocalSnapshot { #[derive(Clone, Debug)] enum ScanState { Idle, - Scanning, + /// The worktree is performing its initial scan of the filesystem. + Initializing, + /// The worktree is updating in response to filesystem events. + Updating, Err(Arc), } @@ -334,7 +337,7 @@ impl Worktree { Self::Local(worktree) => { let is_fake_fs = worktree.fs.is_fake(); worktree.snapshot = worktree.background_snapshot.lock().clone(); - if worktree.is_scanning() { + if matches!(worktree.scan_state(), ScanState::Initializing) { if worktree.poll_task.is_none() { worktree.poll_task = Some(cx.spawn_weak(|this, mut cx| async move { if is_fake_fs { @@ -390,7 +393,8 @@ impl LocalWorktree { .context("failed to stat worktree path")?; let (scan_states_tx, mut scan_states_rx) = mpsc::unbounded(); - let (mut last_scan_state_tx, last_scan_state_rx) = watch::channel_with(ScanState::Scanning); + let (mut last_scan_state_tx, last_scan_state_rx) = + watch::channel_with(ScanState::Initializing); let tree = cx.add_model(move |cx: &mut ModelContext| { let mut snapshot = LocalSnapshot { abs_path, @@ -527,18 +531,14 @@ impl LocalWorktree { let mut scan_state_rx = self.last_scan_state_rx.clone(); async move { let mut scan_state = Some(scan_state_rx.borrow().clone()); - while let Some(ScanState::Scanning) = scan_state { + while let Some(ScanState::Initializing | ScanState::Updating) = scan_state { scan_state = scan_state_rx.recv().await; } } } - fn is_scanning(&self) -> bool { - if let ScanState::Scanning = *self.last_scan_state_rx.borrow() { - true - } else { - false - } + fn scan_state(&self) -> ScanState { + self.last_scan_state_rx.borrow().clone() } pub fn snapshot(&self) -> LocalSnapshot { @@ -947,7 +947,7 @@ impl LocalWorktree { fn broadcast_snapshot(&self) -> impl Future { let mut to_send = None; - if !self.is_scanning() { + if matches!(self.scan_state(), ScanState::Idle) { if let Some(share) = self.share.as_ref() { to_send = Some((self.snapshot(), share.snapshots_tx.clone())); } @@ -1975,7 +1975,7 @@ impl BackgroundScanner { } async fn run(mut self, events_rx: impl Stream>) { - if self.notify.unbounded_send(ScanState::Scanning).is_err() { + if self.notify.unbounded_send(ScanState::Initializing).is_err() { return; } @@ -2000,7 +2000,7 @@ impl BackgroundScanner { events.extend(additional_events); } - if self.notify.unbounded_send(ScanState::Scanning).is_err() { + if self.notify.unbounded_send(ScanState::Updating).is_err() { break; }