Send guests DiskBasedDiagnosticsFinished messages when they join a project

Max Brunsfeld and Antonio Scandurra created

Co-authored-by: Antonio Scandurra <antonio@zed.dev>

Change summary

crates/collab/src/integration_tests.rs | 50 ++++++++++++++++-----------
crates/collab/src/rpc.rs               | 15 ++++++++
crates/project/src/project.rs          | 14 +++---
3 files changed, 52 insertions(+), 27 deletions(-)

Detailed changes

crates/collab/src/integration_tests.rs 🔗

@@ -2161,9 +2161,8 @@ async fn test_collaborating_with_diagnostics(
     let (project_a, worktree_id) = client_a.build_local_project("/a", cx_a).await;
 
     // Cause the language server to start.
-    let _buffer = cx_a
-        .background()
-        .spawn(project_a.update(cx_a, |project, cx| {
+    let _buffer = project_a
+        .update(cx_a, |project, cx| {
             project.open_buffer(
                 ProjectPath {
                     worktree_id,
@@ -2171,7 +2170,7 @@ async fn test_collaborating_with_diagnostics(
                 },
                 cx,
             )
-        }))
+        })
         .await
         .unwrap();
 
@@ -2245,24 +2244,35 @@ async fn test_collaborating_with_diagnostics(
 
     // Join project as client C and observe the diagnostics.
     let project_c = client_c.build_remote_project(project_id, cx_c).await;
-    deterministic.run_until_parked();
-    project_c.read_with(cx_c, |project, cx| {
-        assert_eq!(
-            project.diagnostic_summaries(cx).collect::<Vec<_>>(),
-            &[(
-                ProjectPath {
-                    worktree_id,
-                    path: Arc::from(Path::new("a.rs")),
-                },
-                DiagnosticSummary {
-                    error_count: 1,
-                    warning_count: 0,
-                    ..Default::default()
-                },
-            )]
-        )
+    let project_c_diagnostic_summaries = Rc::new(RefCell::new(Vec::new()));
+    project_c.update(cx_c, |_, cx| {
+        let summaries = project_c_diagnostic_summaries.clone();
+        cx.subscribe(&project_c, {
+            move |p, _, event, cx| {
+                if let project::Event::DiskBasedDiagnosticsFinished { .. } = event {
+                    *summaries.borrow_mut() = p.diagnostic_summaries(cx).collect();
+                }
+            }
+        })
+        .detach();
     });
 
+    deterministic.run_until_parked();
+    assert_eq!(
+        project_c_diagnostic_summaries.borrow().as_slice(),
+        &[(
+            ProjectPath {
+                worktree_id,
+                path: Arc::from(Path::new("a.rs")),
+            },
+            DiagnosticSummary {
+                error_count: 1,
+                warning_count: 0,
+                ..Default::default()
+            },
+        )]
+    );
+
     // Simulate a language server reporting more errors for a file.
     fake_language_server.notify::<lsp::notification::PublishDiagnostics>(
         lsp::PublishDiagnosticsParams {

crates/collab/src/rpc.rs 🔗

@@ -1012,6 +1012,21 @@ impl Server {
             }
         }
 
+        for language_server in &project.language_servers {
+            self.peer.send(
+                request.sender_id,
+                proto::UpdateLanguageServer {
+                    project_id: project_id.to_proto(),
+                    language_server_id: language_server.id,
+                    variant: Some(
+                        proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
+                            proto::LspDiskBasedDiagnosticsUpdated {},
+                        ),
+                    ),
+                },
+            )?;
+        }
+
         Ok(())
     }
 

crates/project/src/project.rs 🔗

@@ -1084,13 +1084,6 @@ impl Project {
                 }
             }
 
-            for worktree in self.worktrees(cx).collect::<Vec<_>>() {
-                worktree.update(cx, |worktree, cx| {
-                    let worktree = worktree.as_local_mut().unwrap();
-                    worktree_share_tasks.push(worktree.share(project_id, cx));
-                });
-            }
-
             for (server_id, status) in &self.language_server_statuses {
                 self.client
                     .send(proto::StartLanguageServer {
@@ -1103,6 +1096,13 @@ impl Project {
                     .log_err();
             }
 
+            for worktree in self.worktrees(cx).collect::<Vec<_>>() {
+                worktree.update(cx, |worktree, cx| {
+                    let worktree = worktree.as_local_mut().unwrap();
+                    worktree_share_tasks.push(worktree.share(project_id, cx));
+                });
+            }
+
             self.client_subscriptions
                 .push(self.client.add_model_for_remote_entity(project_id, cx));
             self.metadata_changed(cx);