aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/reload.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/reload.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/reload.rs')
-rw-r--r--crates/rust-analyzer/src/reload.rs24
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;
19pub(crate) enum ProjectWorkspaceProgress { 19pub(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
25impl GlobalState { 25impl 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);