From bae85d858eca1934112ef0bfa5ed8844fd7e2fd7 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Mon, 21 Oct 2024 11:23:19 -0700 Subject: [PATCH] SSH Remoting: Fix reload/save race (#19519) Release Notes: - N/A Co-authored-by: Conrad Irwin --- crates/language/src/buffer.rs | 4 +++- crates/multi_buffer/src/multi_buffer.rs | 3 ++- crates/project/src/buffer_store.rs | 11 ++++------- crates/project/src/project.rs | 6 ++++++ crates/remote_server/src/remote_editing_tests.rs | 12 ++++++++++++ 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 132ace6683..13c07e014c 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -336,6 +336,8 @@ pub enum BufferEvent { FileHandleChanged, /// The buffer was reloaded. Reloaded, + /// The buffer is in need of a reload + ReloadNeeded, /// The buffer's diff_base changed. DiffBaseChanged, /// Buffer's excerpts for a certain diff base were recalculated. @@ -1077,7 +1079,7 @@ impl Buffer { file_changed = true; if !self.is_dirty() { - self.reload(cx).close(); + cx.emit(BufferEvent::ReloadNeeded); } } } diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index d19ec4501f..5dad354a39 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -94,6 +94,7 @@ pub enum Event { transaction_id: TransactionId, }, Reloaded, + ReloadNeeded, DiffBaseChanged, DiffUpdated { buffer: Model, @@ -1735,6 +1736,7 @@ impl MultiBuffer { language::BufferEvent::Saved => Event::Saved, language::BufferEvent::FileHandleChanged => Event::FileHandleChanged, language::BufferEvent::Reloaded => Event::Reloaded, + language::BufferEvent::ReloadNeeded => Event::ReloadNeeded, language::BufferEvent::DiffBaseChanged => Event::DiffBaseChanged, language::BufferEvent::DiffUpdated => Event::DiffUpdated { buffer }, language::BufferEvent::LanguageChanged => { @@ -1748,7 +1750,6 @@ impl MultiBuffer { self.capability = buffer.read(cx).capability(); Event::CapabilityChanged } - // language::BufferEvent::Operation { .. } => return, }); diff --git a/crates/project/src/buffer_store.rs b/crates/project/src/buffer_store.rs index 9f9e624d22..8948ed6ee7 100644 --- a/crates/project/src/buffer_store.rs +++ b/crates/project/src/buffer_store.rs @@ -54,7 +54,7 @@ trait BufferStoreImpl { fn reload_buffers( &self, - buffers: Vec>, + buffers: HashSet>, push_to_history: bool, cx: &mut ModelContext, ) -> Task>; @@ -392,7 +392,7 @@ impl BufferStoreImpl for Model { fn reload_buffers( &self, - buffers: Vec>, + buffers: HashSet>, push_to_history: bool, cx: &mut ModelContext, ) -> Task> { @@ -938,7 +938,7 @@ impl BufferStoreImpl for Model { fn reload_buffers( &self, - buffers: Vec>, + buffers: HashSet>, push_to_history: bool, cx: &mut ModelContext, ) -> Task> { @@ -1894,13 +1894,10 @@ impl BufferStore { push_to_history: bool, cx: &mut ModelContext, ) -> Task> { - let buffers: Vec> = buffers - .into_iter() - .filter(|buffer| buffer.read(cx).is_dirty()) - .collect(); if buffers.is_empty() { return Task::ready(Ok(ProjectTransaction::default())); } + self.state.reload_buffers(buffers, push_to_history, cx) } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 8ea9e78cb7..c4c33a58d1 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2312,6 +2312,12 @@ impl Project { let buffer_id = buffer.read(cx).remote_id(); match event { + BufferEvent::ReloadNeeded => { + if !self.is_via_collab() { + self.reload_buffers([buffer.clone()].into_iter().collect(), false, cx) + .detach_and_log_err(cx); + } + } BufferEvent::Operation { operation, is_local: true, diff --git a/crates/remote_server/src/remote_editing_tests.rs b/crates/remote_server/src/remote_editing_tests.rs index c46448477c..2835dc9635 100644 --- a/crates/remote_server/src/remote_editing_tests.rs +++ b/crates/remote_server/src/remote_editing_tests.rs @@ -479,7 +479,19 @@ async fn test_remote_reload(cx: &mut TestAppContext, server_cx: &mut TestAppCont }) .await .unwrap(); + + fs.save( + &PathBuf::from("/code/project1/src/lib.rs"), + &("bangles".to_string().into()), + LineEnding::Unix, + ) + .await + .unwrap(); + + cx.run_until_parked(); + buffer.update(cx, |buffer, cx| { + assert_eq!(buffer.text(), "bangles"); buffer.edit([(0..0, "a")], None, cx); });