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/reload.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/reload.rs')
-rw-r--r-- | crates/rust-analyzer/src/reload.rs | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index f4e084741..accf2ef8c 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs | |||
@@ -19,7 +19,7 @@ use lsp_ext::StatusParams; | |||
19 | pub(crate) enum ProjectWorkspaceProgress { | 19 | pub(crate) enum ProjectWorkspaceProgress { |
20 | Begin, | 20 | Begin, |
21 | Report(String), | 21 | Report(String), |
22 | End, | 22 | End(Vec<anyhow::Result<ProjectWorkspace>>), |
23 | } | 23 | } |
24 | 24 | ||
25 | impl GlobalState { | 25 | impl GlobalState { |
@@ -30,7 +30,7 @@ impl GlobalState { | |||
30 | self.analysis_host.update_lru_capacity(self.config.lru_capacity()); | 30 | self.analysis_host.update_lru_capacity(self.config.lru_capacity()); |
31 | } | 31 | } |
32 | if self.config.linked_projects() != old_config.linked_projects() { | 32 | if self.config.linked_projects() != old_config.linked_projects() { |
33 | self.fetch_workspaces() | 33 | self.fetch_workspaces_request() |
34 | } else if self.config.flycheck() != old_config.flycheck() { | 34 | } else if self.config.flycheck() != old_config.flycheck() { |
35 | self.reload_flycheck(); | 35 | self.reload_flycheck(); |
36 | } | 36 | } |
@@ -44,7 +44,7 @@ impl GlobalState { | |||
44 | Status::Ready | Status::Invalid => (), | 44 | Status::Ready | Status::Invalid => (), |
45 | } | 45 | } |
46 | if self.config.cargo_autoreload() { | 46 | if self.config.cargo_autoreload() { |
47 | self.fetch_workspaces(); | 47 | self.fetch_workspaces_request(); |
48 | } else { | 48 | } else { |
49 | self.transition(Status::NeedsReload); | 49 | self.transition(Status::NeedsReload); |
50 | } | 50 | } |
@@ -98,8 +98,15 @@ impl GlobalState { | |||
98 | }); | 98 | }); |
99 | } | 99 | } |
100 | } | 100 | } |
101 | pub(crate) fn fetch_workspaces(&mut self) { | 101 | |
102 | pub(crate) fn fetch_workspaces_request(&mut self) { | ||
103 | self.fetch_workspaces_queue.request_op() | ||
104 | } | ||
105 | pub(crate) fn fetch_workspaces_if_needed(&mut self) { | ||
102 | log::info!("will fetch workspaces"); | 106 | log::info!("will fetch workspaces"); |
107 | if !self.fetch_workspaces_queue.should_start_op() { | ||
108 | return; | ||
109 | } | ||
103 | 110 | ||
104 | self.task_pool.handle.spawn_with_sender({ | 111 | self.task_pool.handle.spawn_with_sender({ |
105 | let linked_projects = self.config.linked_projects(); | 112 | let linked_projects = self.config.linked_projects(); |
@@ -133,12 +140,17 @@ impl GlobalState { | |||
133 | }) | 140 | }) |
134 | .collect::<Vec<_>>(); | 141 | .collect::<Vec<_>>(); |
135 | 142 | ||
136 | sender.send(Task::FetchWorkspace(ProjectWorkspaceProgress::End)).unwrap(); | ||
137 | log::info!("did fetch workspaces {:?}", workspaces); | 143 | log::info!("did fetch workspaces {:?}", workspaces); |
138 | sender.send(Task::Workspaces(workspaces)).unwrap() | 144 | sender |
145 | .send(Task::FetchWorkspace(ProjectWorkspaceProgress::End(workspaces))) | ||
146 | .unwrap(); | ||
139 | } | 147 | } |
140 | }); | 148 | }); |
141 | } | 149 | } |
150 | pub(crate) fn fetch_workspaces_completed(&mut self) { | ||
151 | self.fetch_workspaces_queue.op_completed() | ||
152 | } | ||
153 | |||
142 | pub(crate) fn switch_workspaces(&mut self, workspaces: Vec<anyhow::Result<ProjectWorkspace>>) { | 154 | pub(crate) fn switch_workspaces(&mut self, workspaces: Vec<anyhow::Result<ProjectWorkspace>>) { |
143 | let _p = profile::span("GlobalState::switch_workspaces"); | 155 | let _p = profile::span("GlobalState::switch_workspaces"); |
144 | log::info!("will switch workspaces: {:?}", workspaces); | 156 | log::info!("will switch workspaces: {:?}", workspaces); |