diff options
author | Aleksey Kladov <[email protected]> | 2021-01-10 15:02:02 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-01-10 15:02:02 +0000 |
commit | 2ed258ba423788e95885d43724bb9fc1761cc776 (patch) | |
tree | b4f099cf99710feb2fc6684002813fb8682726c2 /crates/rust-analyzer/src/main_loop.rs | |
parent | 77362c71735a8b5ab4b5cd9f396fa657fbffe2cb (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.rs | 16 |
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}; | |||
11 | use ide_db::base_db::VfsPath; | 11 | use ide_db::base_db::VfsPath; |
12 | use lsp_server::{Connection, Notification, Request, Response}; | 12 | use lsp_server::{Connection, Notification, Request, Response}; |
13 | use lsp_types::notification::Notification as _; | 13 | use lsp_types::notification::Notification as _; |
14 | use project_model::ProjectWorkspace; | ||
15 | use vfs::ChangeKind; | 14 | use vfs::ChangeKind; |
16 | 15 | ||
17 | use crate::{ | 16 | use crate::{ |
@@ -62,7 +61,6 @@ enum Event { | |||
62 | pub(crate) enum Task { | 61 | pub(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, ()| { |