Use read-only access methods for read-only entity operations (#31254)

Joseph T. Lyons created

This PR replaces some `update()` calls with either `read()` or
`read_with()` when the `update()` call performed read-only operations on
the entity.

Many more likely exist, will follow-up with more PRs.

Release Notes:

- N/A

Change summary

crates/agent/src/context_picker/completion_provider.rs |  2 +-
crates/agent/src/inline_prompt_editor.rs               |  4 +---
crates/agent/src/thread.rs                             |  6 ++++--
crates/auto_update/src/auto_update.rs                  |  2 +-
crates/channel/src/channel_store_tests.rs              |  2 +-
crates/collab/src/tests/following_tests.rs             |  2 +-
crates/collab/src/tests/integration_tests.rs           |  6 +++---
crates/debugger_ui/src/tests/console.rs                |  2 +-
crates/debugger_ui/src/tests/debugger_panel.rs         |  2 +-
crates/search/src/buffer_search.rs                     | 10 +++++-----
crates/tab_switcher/src/tab_switcher_tests.rs          |  2 +-
11 files changed, 20 insertions(+), 20 deletions(-)

Detailed changes

crates/agent/src/context_picker/completion_provider.rs 🔗

@@ -1213,7 +1213,7 @@ mod tests {
             assert_eq!(worktrees.len(), 1);
             worktrees.pop().unwrap()
         });
-        let worktree_id = worktree.update(cx, |worktree, _| worktree.id());
+        let worktree_id = worktree.read_with(cx, |worktree, _| worktree.id());
 
         let mut cx = VisualTestContext::from_window(*window.deref(), cx);
 

crates/agent/src/inline_prompt_editor.rs 🔗

@@ -326,9 +326,7 @@ impl<T: 'static> PromptEditor<T> {
             EditorEvent::Edited { .. } => {
                 if let Some(workspace) = window.root::<Workspace>().flatten() {
                     workspace.update(cx, |workspace, cx| {
-                        let is_via_ssh = workspace
-                            .project()
-                            .update(cx, |project, _| project.is_via_ssh());
+                        let is_via_ssh = workspace.project().read(cx).is_via_ssh();
 
                         workspace
                             .client()

crates/agent/src/thread.rs 🔗

@@ -2851,7 +2851,8 @@ mod tests {
             .await
             .unwrap();
 
-        let context = context_store.update(cx, |store, _| store.context().next().cloned().unwrap());
+        let context =
+            context_store.read_with(cx, |store, _| store.context().next().cloned().unwrap());
         let loaded_context = cx
             .update(|cx| load_context(vec![context], &project, &None, cx))
             .await;
@@ -3162,7 +3163,8 @@ fn main() {{
             .await
             .unwrap();
 
-        let context = context_store.update(cx, |store, _| store.context().next().cloned().unwrap());
+        let context =
+            context_store.read_with(cx, |store, _| store.context().next().cloned().unwrap());
         let loaded_context = cx
             .update(|cx| load_context(vec![context], &project, &None, cx))
             .await;

crates/auto_update/src/auto_update.rs 🔗

@@ -493,7 +493,7 @@ impl AutoUpdater {
 
     async fn update(this: Entity<Self>, mut cx: AsyncApp) -> Result<()> {
         let (client, installed_version, previous_status, release_channel) =
-            this.update(&mut cx, |this, cx| {
+            this.read_with(&mut cx, |this, cx| {
                 (
                     this.http_client.clone(),
                     this.current_version,

crates/channel/src/channel_store_tests.rs 🔗

@@ -137,7 +137,7 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
     let user_id = 5;
     let channel_id = 5;
     let channel_store = cx.update(init_test);
-    let client = channel_store.update(cx, |s, _| s.client());
+    let client = channel_store.read_with(cx, |s, _| s.client());
     let server = FakeServer::for_client(user_id, &client, cx).await;
 
     // Get the available channels.

crates/collab/src/tests/following_tests.rs 🔗

@@ -2066,7 +2066,7 @@ async fn share_workspace(
     workspace: &Entity<Workspace>,
     cx: &mut VisualTestContext,
 ) -> anyhow::Result<u64> {
-    let project = workspace.update(cx, |workspace, _| workspace.project().clone());
+    let project = workspace.read_with(cx, |workspace, _| workspace.project().clone());
     cx.read(ActiveCall::global)
         .update(cx, |call, cx| call.share_project(project, cx))
         .await

crates/collab/src/tests/integration_tests.rs 🔗

@@ -6416,7 +6416,7 @@ async fn test_join_after_restart(cx1: &mut TestAppContext, cx2: &mut TestAppCont
 async fn test_preview_tabs(cx: &mut TestAppContext) {
     let (_server, client) = TestServer::start1(cx).await;
     let (workspace, cx) = client.build_test_workspace(cx).await;
-    let project = workspace.update(cx, |workspace, _| workspace.project().clone());
+    let project = workspace.read_with(cx, |workspace, _| workspace.project().clone());
 
     let worktree_id = project.update(cx, |project, cx| {
         project.worktrees(cx).next().unwrap().read(cx).id()
@@ -6435,7 +6435,7 @@ async fn test_preview_tabs(cx: &mut TestAppContext) {
         path: Path::new("3.rs").into(),
     };
 
-    let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
+    let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
 
     let get_path = |pane: &Pane, idx: usize, cx: &App| {
         pane.item_for_index(idx).unwrap().project_path(cx).unwrap()
@@ -6588,7 +6588,7 @@ async fn test_preview_tabs(cx: &mut TestAppContext) {
         pane.split(workspace::SplitDirection::Right, cx);
     });
 
-    let right_pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
+    let right_pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
 
     pane.update(cx, |pane, cx| {
         assert_eq!(pane.items_len(), 1);

crates/debugger_ui/src/tests/console.rs 🔗

@@ -33,7 +33,7 @@ async fn test_handle_output_event(executor: BackgroundExecutor, cx: &mut TestApp
         .unwrap();
 
     let session = start_debug_session(&workspace, cx, |_| {}).unwrap();
-    let client = session.update(cx, |session, _| session.adapter_client().unwrap());
+    let client = session.read_with(cx, |session, _| session.adapter_client().unwrap());
 
     client.on_request::<StackTrace, _>(move |_, _| {
         Ok(dap::StackTraceResponse {

crates/debugger_ui/src/tests/debugger_panel.rs 🔗

@@ -1015,7 +1015,7 @@ async fn test_debug_panel_item_thread_status_reset_on_failure(
     cx.run_until_parked();
 
     let running_state = active_debug_session_panel(workspace, cx)
-        .update(cx, |item, _| item.running_state().clone());
+        .read_with(cx, |item, _| item.running_state().clone());
 
     cx.run_until_parked();
     let thread_id = ThreadId(1);

crates/search/src/buffer_search.rs 🔗

@@ -2397,7 +2397,7 @@ mod tests {
             search_bar.replace_all(&ReplaceAll, window, cx)
         });
         assert_eq!(
-            editor.update(cx, |this, cx| { this.text(cx) }),
+            editor.read_with(cx, |this, cx| { this.text(cx) }),
             r#"
         A regular expr$1 (shortened as regex or regexp;[1] also referred to as
         rational expr$1[2][3]) is a sequence of characters that specifies a search
@@ -2423,7 +2423,7 @@ mod tests {
         });
         // Notice how the first or in the text (shORtened) is not replaced. Neither are the remaining hits of `or` in the text.
         assert_eq!(
-            editor.update(cx, |this, cx| { this.text(cx) }),
+            editor.read_with(cx, |this, cx| { this.text(cx) }),
             r#"
         A regular expr$1 (shortened as regex banana regexp;[1] also referred to as
         rational expr$1[2][3]) is a sequence of characters that specifies a search
@@ -2446,7 +2446,7 @@ mod tests {
             search_bar.replace_all(&ReplaceAll, window, cx)
         });
         assert_eq!(
-            editor.update(cx, |this, cx| { this.text(cx) }),
+            editor.read_with(cx, |this, cx| { this.text(cx) }),
             r#"
         A regular expr$1 (shortened as regex banana regexp;1number also referred to as
         rational expr$12number3number) is a sequence of characters that specifies a search
@@ -2476,7 +2476,7 @@ mod tests {
         // The only word affected by this edit should be `algorithms`, even though there's a bunch
         // of words in this text that would match this regex if not for WHOLE_WORD.
         assert_eq!(
-            editor.update(cx, |this, cx| { this.text(cx) }),
+            editor.read_with(cx, |this, cx| { this.text(cx) }),
             r#"
         A regular expr$1 (shortened as regex banana regexp;1number also referred to as
         rational expr$12number3number) is a sequence of characters that specifies a search
@@ -2527,7 +2527,7 @@ mod tests {
         assert_eq!(
             options
                 .editor
-                .update(options.cx, |this, cx| { this.text(cx) }),
+                .read_with(options.cx, |this, cx| { this.text(cx) }),
             options.expected_text
         );
     }

crates/tab_switcher/src/tab_switcher_tests.rs 🔗

@@ -326,7 +326,7 @@ async fn open_buffer(
     workspace: &Entity<Workspace>,
     cx: &mut gpui::VisualTestContext,
 ) -> Box<dyn ItemHandle> {
-    let project = workspace.update(cx, |workspace, _| workspace.project().clone());
+    let project = workspace.read_with(cx, |workspace, _| workspace.project().clone());
     let worktree_id = project.update(cx, |project, cx| {
         let worktree = project.worktrees(cx).last().expect("worktree not found");
         worktree.read(cx).id()