Merge pull request #21164 from Wilfred/multiple_discover_requests
fix: Allow multiple discover operations
This commit is contained in:
commit
95cee9cccf
5 changed files with 69 additions and 30 deletions
|
|
@ -197,4 +197,22 @@ impl<T: Sized + Send + 'static> CommandHandle<T> {
|
|||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn has_exited(&mut self) -> bool {
|
||||
match self.child.0.try_wait() {
|
||||
Ok(Some(_exit_code)) => {
|
||||
// We have an exit code.
|
||||
true
|
||||
}
|
||||
Ok(None) => {
|
||||
// Hasn't exited yet.
|
||||
false
|
||||
}
|
||||
Err(_) => {
|
||||
// Couldn't get an exit code. Assume that we've
|
||||
// exited.
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ impl DiscoverCommand {
|
|||
cmd.args(args);
|
||||
|
||||
Ok(DiscoverHandle {
|
||||
_handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone(), None)?,
|
||||
handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone(), None)?,
|
||||
span: info_span!("discover_command").entered(),
|
||||
})
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ impl DiscoverCommand {
|
|||
/// A handle to a spawned [Discover].
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct DiscoverHandle {
|
||||
_handle: CommandHandle<DiscoverProjectMessage>,
|
||||
pub(crate) handle: CommandHandle<DiscoverProjectMessage>,
|
||||
#[allow(dead_code)] // not accessed, but used to log on drop.
|
||||
span: EnteredSpan,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,9 +121,10 @@ pub(crate) struct GlobalState {
|
|||
pub(crate) test_run_remaining_jobs: usize,
|
||||
|
||||
// Project loading
|
||||
pub(crate) discover_handle: Option<discover::DiscoverHandle>,
|
||||
pub(crate) discover_handles: Vec<discover::DiscoverHandle>,
|
||||
pub(crate) discover_sender: Sender<discover::DiscoverProjectMessage>,
|
||||
pub(crate) discover_receiver: Receiver<discover::DiscoverProjectMessage>,
|
||||
pub(crate) discover_jobs_active: u32,
|
||||
|
||||
// Debouncing channel for fetching the workspace
|
||||
// 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 {
|
|||
pub(crate) fetch_build_data_queue: OpQueue<(), FetchBuildDataResponse>,
|
||||
pub(crate) fetch_proc_macros_queue: OpQueue<(ChangeWithProcMacros, Vec<ProcMacroPaths>), bool>,
|
||||
pub(crate) prime_caches_queue: OpQueue,
|
||||
pub(crate) discover_workspace_queue: OpQueue,
|
||||
|
||||
/// A deferred task queue.
|
||||
///
|
||||
|
|
@ -292,9 +292,10 @@ impl GlobalState {
|
|||
test_run_receiver,
|
||||
test_run_remaining_jobs: 0,
|
||||
|
||||
discover_handle: None,
|
||||
discover_handles: vec![],
|
||||
discover_sender,
|
||||
discover_receiver,
|
||||
discover_jobs_active: 0,
|
||||
|
||||
fetch_ws_receiver: None,
|
||||
|
||||
|
|
@ -313,7 +314,6 @@ impl GlobalState {
|
|||
fetch_proc_macros_queue: OpQueue::default(),
|
||||
|
||||
prime_caches_queue: OpQueue::default(),
|
||||
discover_workspace_queue: OpQueue::default(),
|
||||
|
||||
deferred_task_queue,
|
||||
incomplete_crate_graph: false,
|
||||
|
|
|
|||
|
|
@ -531,6 +531,8 @@ impl GlobalState {
|
|||
}
|
||||
}
|
||||
|
||||
self.cleanup_discover_handles();
|
||||
|
||||
if let Some(diagnostic_changes) = self.diagnostics.take_changes() {
|
||||
for file_id in diagnostic_changes {
|
||||
let uri = file_id_to_url(&self.vfs.read().0, file_id);
|
||||
|
|
@ -806,33 +808,34 @@ impl GlobalState {
|
|||
self.report_progress("Fetching", state, msg, None, None);
|
||||
}
|
||||
Task::DiscoverLinkedProjects(arg) => {
|
||||
if let Some(cfg) = self.config.discover_workspace_config()
|
||||
&& !self.discover_workspace_queue.op_in_progress()
|
||||
{
|
||||
if let Some(cfg) = self.config.discover_workspace_config() {
|
||||
// the clone is unfortunately necessary to avoid a borrowck error when
|
||||
// `self.report_progress` is called later
|
||||
let title = &cfg.progress_label.clone();
|
||||
let command = cfg.command.clone();
|
||||
let discover = DiscoverCommand::new(self.discover_sender.clone(), command);
|
||||
|
||||
self.report_progress(title, Progress::Begin, None, None, None);
|
||||
self.discover_workspace_queue
|
||||
.request_op("Discovering workspace".to_owned(), ());
|
||||
let _ = self.discover_workspace_queue.should_start_op();
|
||||
if self.discover_jobs_active == 0 {
|
||||
self.report_progress(title, Progress::Begin, None, None, None);
|
||||
}
|
||||
self.discover_jobs_active += 1;
|
||||
|
||||
let arg = match arg {
|
||||
DiscoverProjectParam::Buildfile(it) => DiscoverArgument::Buildfile(it),
|
||||
DiscoverProjectParam::Path(it) => DiscoverArgument::Path(it),
|
||||
};
|
||||
|
||||
let handle = discover.spawn(
|
||||
arg,
|
||||
&std::env::current_dir()
|
||||
.expect("Failed to get cwd during project discovery"),
|
||||
);
|
||||
self.discover_handle = Some(handle.unwrap_or_else(|e| {
|
||||
panic!("Failed to spawn project discovery command: {e}")
|
||||
}));
|
||||
let handle = discover
|
||||
.spawn(
|
||||
arg,
|
||||
&std::env::current_dir()
|
||||
.expect("Failed to get cwd during project discovery"),
|
||||
)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!("Failed to spawn project discovery command: {e}")
|
||||
});
|
||||
|
||||
self.discover_handles.push(handle);
|
||||
}
|
||||
}
|
||||
Task::FetchBuildData(progress) => {
|
||||
|
|
@ -1036,27 +1039,45 @@ impl GlobalState {
|
|||
.expect("No title could be found; this is a bug");
|
||||
match message {
|
||||
DiscoverProjectMessage::Finished { project, buildfile } => {
|
||||
self.discover_handle = None;
|
||||
self.report_progress(&title, Progress::End, None, None, None);
|
||||
self.discover_workspace_queue.op_completed(());
|
||||
self.discover_jobs_active = self.discover_jobs_active.saturating_sub(1);
|
||||
if self.discover_jobs_active == 0 {
|
||||
self.report_progress(&title, Progress::End, None, None, None);
|
||||
}
|
||||
|
||||
let mut config = Config::clone(&*self.config);
|
||||
config.add_discovered_project_from_command(project, buildfile);
|
||||
self.update_configuration(config);
|
||||
}
|
||||
DiscoverProjectMessage::Progress { message } => {
|
||||
self.report_progress(&title, Progress::Report, Some(message), None, None)
|
||||
if self.discover_jobs_active > 0 {
|
||||
self.report_progress(&title, Progress::Report, Some(message), None, None)
|
||||
}
|
||||
}
|
||||
DiscoverProjectMessage::Error { error, source } => {
|
||||
self.discover_handle = None;
|
||||
let message = format!("Project discovery failed: {error}");
|
||||
self.discover_workspace_queue.op_completed(());
|
||||
self.show_and_log_error(message.clone(), source);
|
||||
self.report_progress(&title, Progress::End, Some(message), None, None)
|
||||
|
||||
self.discover_jobs_active = self.discover_jobs_active.saturating_sub(1);
|
||||
if self.discover_jobs_active == 0 {
|
||||
self.report_progress(&title, Progress::End, Some(message), None, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Drop any discover command processes that have exited, due to
|
||||
/// finishing or erroring.
|
||||
fn cleanup_discover_handles(&mut self) {
|
||||
let mut active_handles = vec![];
|
||||
|
||||
for mut discover_handle in self.discover_handles.drain(..) {
|
||||
if !discover_handle.handle.has_exited() {
|
||||
active_handles.push(discover_handle);
|
||||
}
|
||||
}
|
||||
self.discover_handles = active_handles;
|
||||
}
|
||||
|
||||
fn handle_cargo_test_msg(&mut self, message: CargoTestMessage) {
|
||||
match message.output {
|
||||
CargoTestOutput::Test { name, state } => {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ impl GlobalState {
|
|||
&& !self.fetch_workspaces_queue.op_in_progress()
|
||||
&& !self.fetch_build_data_queue.op_in_progress()
|
||||
&& !self.fetch_proc_macros_queue.op_in_progress()
|
||||
&& !self.discover_workspace_queue.op_in_progress()
|
||||
&& self.discover_jobs_active == 0
|
||||
&& self.vfs_progress_config_version >= self.vfs_config_version
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ impl GlobalState {
|
|||
.collect();
|
||||
let cargo_config = self.config.cargo(None);
|
||||
let discover_command = self.config.discover_workspace_config().cloned();
|
||||
let is_quiescent = !(self.discover_workspace_queue.op_in_progress()
|
||||
let is_quiescent = !(self.discover_jobs_active > 0
|
||||
|| self.vfs_progress_config_version < self.vfs_config_version
|
||||
|| !self.vfs_done);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue