aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/main_loop.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-01-10 15:02:02 +0000
committerAleksey Kladov <[email protected]>2021-01-10 15:02:02 +0000
commit2ed258ba423788e95885d43724bb9fc1761cc776 (patch)
treeb4f099cf99710feb2fc6684002813fb8682726c2 /crates/rust-analyzer/src/main_loop.rs
parent77362c71735a8b5ab4b5cd9f396fa657fbffe2cb (diff)
Fix progress token is already registered crash
After we started reporting progress when running cargo check during loading, it is possible to crash the client with two identical progress tokens. This points to a deeper issue: we might be running several cargo checks concurrently, which doesn't make sense. This commit linearizes all workspace fetches, making sure no updates are lost. As an additional touch, it also normalizes progress & result reporting, to make sure they stand in sync.
Diffstat (limited to 'crates/rust-analyzer/src/main_loop.rs')
-rw-r--r--crates/rust-analyzer/src/main_loop.rs16
1 files changed, 10 insertions, 6 deletions
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 22ee96775..51fb2eb74 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -11,7 +11,6 @@ use ide::{Canceled, FileId};
11use ide_db::base_db::VfsPath; 11use ide_db::base_db::VfsPath;
12use lsp_server::{Connection, Notification, Request, Response}; 12use lsp_server::{Connection, Notification, Request, Response};
13use lsp_types::notification::Notification as _; 13use lsp_types::notification::Notification as _;
14use project_model::ProjectWorkspace;
15use vfs::ChangeKind; 14use vfs::ChangeKind;
16 15
17use crate::{ 16use crate::{
@@ -62,7 +61,6 @@ enum Event {
62pub(crate) enum Task { 61pub(crate) enum Task {
63 Response(Response), 62 Response(Response),
64 Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>), 63 Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>),
65 Workspaces(Vec<anyhow::Result<ProjectWorkspace>>),
66 PrimeCaches(PrimeCachesProgress), 64 PrimeCaches(PrimeCachesProgress),
67 FetchWorkspace(ProjectWorkspaceProgress), 65 FetchWorkspace(ProjectWorkspaceProgress),
68} 66}
@@ -143,7 +141,8 @@ impl GlobalState {
143 |_, _| (), 141 |_, _| (),
144 ); 142 );
145 143
146 self.fetch_workspaces(); 144 self.fetch_workspaces_request();
145 self.fetch_workspaces_if_needed();
147 146
148 while let Some(event) = self.next_event(&inbox) { 147 while let Some(event) = self.next_event(&inbox) {
149 if let Event::Lsp(lsp_server::Message::Notification(not)) = &event { 148 if let Event::Lsp(lsp_server::Message::Notification(not)) = &event {
@@ -204,7 +203,6 @@ impl GlobalState {
204 self.diagnostics.set_native_diagnostics(file_id, diagnostics) 203 self.diagnostics.set_native_diagnostics(file_id, diagnostics)
205 } 204 }
206 } 205 }
207 Task::Workspaces(workspaces) => self.switch_workspaces(workspaces),
208 Task::PrimeCaches(progress) => match progress { 206 Task::PrimeCaches(progress) => match progress {
209 PrimeCachesProgress::Started => prime_caches_progress.push(progress), 207 PrimeCachesProgress::Started => prime_caches_progress.push(progress),
210 PrimeCachesProgress::StartedOnCrate { .. } => { 208 PrimeCachesProgress::StartedOnCrate { .. } => {
@@ -224,7 +222,11 @@ impl GlobalState {
224 ProjectWorkspaceProgress::Report(msg) => { 222 ProjectWorkspaceProgress::Report(msg) => {
225 (Progress::Report, Some(msg)) 223 (Progress::Report, Some(msg))
226 } 224 }
227 ProjectWorkspaceProgress::End => (Progress::End, None), 225 ProjectWorkspaceProgress::End(workspaces) => {
226 self.fetch_workspaces_completed();
227 self.switch_workspaces(workspaces);
228 (Progress::End, None)
229 }
228 }; 230 };
229 self.report_progress("fetching", state, msg, None); 231 self.report_progress("fetching", state, msg, None);
230 } 232 }
@@ -403,6 +405,8 @@ impl GlobalState {
403 } 405 }
404 } 406 }
405 407
408 self.fetch_workspaces_if_needed();
409
406 let loop_duration = loop_start.elapsed(); 410 let loop_duration = loop_start.elapsed();
407 if loop_duration > Duration::from_millis(100) { 411 if loop_duration > Duration::from_millis(100) {
408 log::warn!("overly long loop turn: {:?}", loop_duration); 412 log::warn!("overly long loop turn: {:?}", loop_duration);
@@ -440,7 +444,7 @@ impl GlobalState {
440 } 444 }
441 445
442 RequestDispatcher { req: Some(req), global_state: self } 446 RequestDispatcher { req: Some(req), global_state: self }
443 .on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))? 447 .on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces_request()))?
444 .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))? 448 .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
445 .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))? 449 .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))?
446 .on_sync::<lsp_types::request::Shutdown>(|s, ()| { 450 .on_sync::<lsp_types::request::Shutdown>(|s, ()| {