Skip to content

Commit 95cee9c

Browse files
authored
Merge pull request #21164 from Wilfred/multiple_discover_requests
fix: Allow multiple discover operations
2 parents 1e3fbf9 + 39cd4a1 commit 95cee9c

File tree

5 files changed

+69
-30
lines changed

5 files changed

+69
-30
lines changed

src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,22 @@ impl<T: Sized + Send + 'static> CommandHandle<T> {
197197
)))
198198
}
199199
}
200+
201+
pub(crate) fn has_exited(&mut self) -> bool {
202+
match self.child.0.try_wait() {
203+
Ok(Some(_exit_code)) => {
204+
// We have an exit code.
205+
true
206+
}
207+
Ok(None) => {
208+
// Hasn't exited yet.
209+
false
210+
}
211+
Err(_) => {
212+
// Couldn't get an exit code. Assume that we've
213+
// exited.
214+
true
215+
}
216+
}
217+
}
200218
}

src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl DiscoverCommand {
6767
cmd.args(args);
6868

6969
Ok(DiscoverHandle {
70-
_handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone(), None)?,
70+
handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone(), None)?,
7171
span: info_span!("discover_command").entered(),
7272
})
7373
}
@@ -76,7 +76,7 @@ impl DiscoverCommand {
7676
/// A handle to a spawned [Discover].
7777
#[derive(Debug)]
7878
pub(crate) struct DiscoverHandle {
79-
_handle: CommandHandle<DiscoverProjectMessage>,
79+
pub(crate) handle: CommandHandle<DiscoverProjectMessage>,
8080
#[allow(dead_code)] // not accessed, but used to log on drop.
8181
span: EnteredSpan,
8282
}

src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,10 @@ pub(crate) struct GlobalState {
121121
pub(crate) test_run_remaining_jobs: usize,
122122

123123
// Project loading
124-
pub(crate) discover_handle: Option<discover::DiscoverHandle>,
124+
pub(crate) discover_handles: Vec<discover::DiscoverHandle>,
125125
pub(crate) discover_sender: Sender<discover::DiscoverProjectMessage>,
126126
pub(crate) discover_receiver: Receiver<discover::DiscoverProjectMessage>,
127+
pub(crate) discover_jobs_active: u32,
127128

128129
// Debouncing channel for fetching the workspace
129130
// we want to delay it until the VFS looks stable-ish (and thus is not currently in the middle
@@ -175,7 +176,6 @@ pub(crate) struct GlobalState {
175176
pub(crate) fetch_build_data_queue: OpQueue<(), FetchBuildDataResponse>,
176177
pub(crate) fetch_proc_macros_queue: OpQueue<(ChangeWithProcMacros, Vec<ProcMacroPaths>), bool>,
177178
pub(crate) prime_caches_queue: OpQueue,
178-
pub(crate) discover_workspace_queue: OpQueue,
179179

180180
/// A deferred task queue.
181181
///
@@ -292,9 +292,10 @@ impl GlobalState {
292292
test_run_receiver,
293293
test_run_remaining_jobs: 0,
294294

295-
discover_handle: None,
295+
discover_handles: vec![],
296296
discover_sender,
297297
discover_receiver,
298+
discover_jobs_active: 0,
298299

299300
fetch_ws_receiver: None,
300301

@@ -313,7 +314,6 @@ impl GlobalState {
313314
fetch_proc_macros_queue: OpQueue::default(),
314315

315316
prime_caches_queue: OpQueue::default(),
316-
discover_workspace_queue: OpQueue::default(),
317317

318318
deferred_task_queue,
319319
incomplete_crate_graph: false,

src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,8 @@ impl GlobalState {
531531
}
532532
}
533533

534+
self.cleanup_discover_handles();
535+
534536
if let Some(diagnostic_changes) = self.diagnostics.take_changes() {
535537
for file_id in diagnostic_changes {
536538
let uri = file_id_to_url(&self.vfs.read().0, file_id);
@@ -806,33 +808,34 @@ impl GlobalState {
806808
self.report_progress("Fetching", state, msg, None, None);
807809
}
808810
Task::DiscoverLinkedProjects(arg) => {
809-
if let Some(cfg) = self.config.discover_workspace_config()
810-
&& !self.discover_workspace_queue.op_in_progress()
811-
{
811+
if let Some(cfg) = self.config.discover_workspace_config() {
812812
// the clone is unfortunately necessary to avoid a borrowck error when
813813
// `self.report_progress` is called later
814814
let title = &cfg.progress_label.clone();
815815
let command = cfg.command.clone();
816816
let discover = DiscoverCommand::new(self.discover_sender.clone(), command);
817817

818-
self.report_progress(title, Progress::Begin, None, None, None);
819-
self.discover_workspace_queue
820-
.request_op("Discovering workspace".to_owned(), ());
821-
let _ = self.discover_workspace_queue.should_start_op();
818+
if self.discover_jobs_active == 0 {
819+
self.report_progress(title, Progress::Begin, None, None, None);
820+
}
821+
self.discover_jobs_active += 1;
822822

823823
let arg = match arg {
824824
DiscoverProjectParam::Buildfile(it) => DiscoverArgument::Buildfile(it),
825825
DiscoverProjectParam::Path(it) => DiscoverArgument::Path(it),
826826
};
827827

828-
let handle = discover.spawn(
829-
arg,
830-
&std::env::current_dir()
831-
.expect("Failed to get cwd during project discovery"),
832-
);
833-
self.discover_handle = Some(handle.unwrap_or_else(|e| {
834-
panic!("Failed to spawn project discovery command: {e}")
835-
}));
828+
let handle = discover
829+
.spawn(
830+
arg,
831+
&std::env::current_dir()
832+
.expect("Failed to get cwd during project discovery"),
833+
)
834+
.unwrap_or_else(|e| {
835+
panic!("Failed to spawn project discovery command: {e}")
836+
});
837+
838+
self.discover_handles.push(handle);
836839
}
837840
}
838841
Task::FetchBuildData(progress) => {
@@ -1036,25 +1039,43 @@ impl GlobalState {
10361039
.expect("No title could be found; this is a bug");
10371040
match message {
10381041
DiscoverProjectMessage::Finished { project, buildfile } => {
1039-
self.discover_handle = None;
1040-
self.report_progress(&title, Progress::End, None, None, None);
1041-
self.discover_workspace_queue.op_completed(());
1042+
self.discover_jobs_active = self.discover_jobs_active.saturating_sub(1);
1043+
if self.discover_jobs_active == 0 {
1044+
self.report_progress(&title, Progress::End, None, None, None);
1045+
}
10421046

10431047
let mut config = Config::clone(&*self.config);
10441048
config.add_discovered_project_from_command(project, buildfile);
10451049
self.update_configuration(config);
10461050
}
10471051
DiscoverProjectMessage::Progress { message } => {
1048-
self.report_progress(&title, Progress::Report, Some(message), None, None)
1052+
if self.discover_jobs_active > 0 {
1053+
self.report_progress(&title, Progress::Report, Some(message), None, None)
1054+
}
10491055
}
10501056
DiscoverProjectMessage::Error { error, source } => {
1051-
self.discover_handle = None;
10521057
let message = format!("Project discovery failed: {error}");
1053-
self.discover_workspace_queue.op_completed(());
10541058
self.show_and_log_error(message.clone(), source);
1055-
self.report_progress(&title, Progress::End, Some(message), None, None)
1059+
1060+
self.discover_jobs_active = self.discover_jobs_active.saturating_sub(1);
1061+
if self.discover_jobs_active == 0 {
1062+
self.report_progress(&title, Progress::End, Some(message), None, None)
1063+
}
1064+
}
1065+
}
1066+
}
1067+
1068+
/// Drop any discover command processes that have exited, due to
1069+
/// finishing or erroring.
1070+
fn cleanup_discover_handles(&mut self) {
1071+
let mut active_handles = vec![];
1072+
1073+
for mut discover_handle in self.discover_handles.drain(..) {
1074+
if !discover_handle.handle.has_exited() {
1075+
active_handles.push(discover_handle);
10561076
}
10571077
}
1078+
self.discover_handles = active_handles;
10581079
}
10591080

10601081
fn handle_cargo_test_msg(&mut self, message: CargoTestMessage) {

src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl GlobalState {
7474
&& !self.fetch_workspaces_queue.op_in_progress()
7575
&& !self.fetch_build_data_queue.op_in_progress()
7676
&& !self.fetch_proc_macros_queue.op_in_progress()
77-
&& !self.discover_workspace_queue.op_in_progress()
77+
&& self.discover_jobs_active == 0
7878
&& self.vfs_progress_config_version >= self.vfs_config_version
7979
}
8080

@@ -297,7 +297,7 @@ impl GlobalState {
297297
.collect();
298298
let cargo_config = self.config.cargo(None);
299299
let discover_command = self.config.discover_workspace_config().cloned();
300-
let is_quiescent = !(self.discover_workspace_queue.op_in_progress()
300+
let is_quiescent = !(self.discover_jobs_active > 0
301301
|| self.vfs_progress_config_version < self.vfs_config_version
302302
|| !self.vfs_done);
303303

0 commit comments

Comments
 (0)