Auto merge of #18180 - kpreid:search, r=davidbarsky
feat: Index workspace symbols at startup rather than on the first symbol search.
This will eliminate potential many-second delays when performing the first search, at the price of making cache priming (“Indexing N/M” in the VS Code status bar) take a little longer in total. Hopefully this additional time is insignificant because a typical session will involve at least one symbol search.
Further improvement would be to do this as a separate parallel task (which will be beneficial if the workspace contains a small number of large crates), but that would require significant additional refactoring of the progress-reporting mechanism to understand multiple tasks per crate. Happy to tackle that in this PR if desired, but I thought I'd propose the minimal change first.
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs
index 7e9162e..96b1642 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs
@@ -7,6 +7,7 @@
use project_model::ProjectJsonData;
use serde::{Deserialize, Serialize};
use serde_json::Value;
+use tracing::{info_span, span::EnteredSpan};
use crate::command::{CommandHandle, ParseFromLine};
@@ -60,7 +61,10 @@
let mut cmd = Command::new(command);
cmd.args(args);
- Ok(DiscoverHandle { _handle: CommandHandle::spawn(cmd, self.sender.clone())? })
+ Ok(DiscoverHandle {
+ _handle: CommandHandle::spawn(cmd, self.sender.clone())?,
+ span: info_span!("discover_command").entered(),
+ })
}
}
@@ -68,6 +72,8 @@
#[derive(Debug)]
pub(crate) struct DiscoverHandle {
_handle: CommandHandle<DiscoverProjectMessage>,
+ #[allow(dead_code)] // not accessed, but used to log on drop.
+ span: EnteredSpan,
}
/// An enum containing either progress messages, an error,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
index 89487aa..874e91a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
@@ -111,6 +111,9 @@
pub(crate) vfs_config_version: u32,
pub(crate) vfs_progress_config_version: u32,
pub(crate) vfs_done: bool,
+ // used to track how long VFS loading takes. this can't be on `vfs::loader::Handle`,
+ // as that handle's lifetime is the same as `GlobalState` itself.
+ pub(crate) vfs_span: Option<tracing::span::EnteredSpan>,
pub(crate) wants_to_switch: Option<Cause>,
/// `workspaces` field stores the data we actually use, while the `OpQueue`
@@ -253,6 +256,7 @@
vfs: Arc::new(RwLock::new((vfs::Vfs::default(), IntMap::default()))),
vfs_config_version: 0,
vfs_progress_config_version: 0,
+ vfs_span: None,
vfs_done: true,
wants_to_switch: None,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
index 8355923..78a302b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -794,13 +794,20 @@
}
}
vfs::loader::Message::Progress { n_total, n_done, dir, config_version } => {
- let _p = tracing::info_span!("GlobalState::handle_vfs_mgs/progress").entered();
+ let _p = span!(Level::INFO, "GlobalState::handle_vfs_mgs/progress").entered();
always!(config_version <= self.vfs_config_version);
let (n_done, state) = match n_done {
- LoadingProgress::Started => (0, Progress::Begin),
+ LoadingProgress::Started => {
+ self.vfs_span =
+ Some(span!(Level::INFO, "vfs_load", total = n_total).entered());
+ (0, Progress::Begin)
+ }
LoadingProgress::Progress(n_done) => (n_done.min(n_total), Progress::Report),
- LoadingProgress::Finished => (n_total, Progress::End),
+ LoadingProgress::Finished => {
+ self.vfs_span = None;
+ (n_total, Progress::End)
+ }
};
self.vfs_progress_config_version = config_version;
@@ -881,6 +888,7 @@
.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(());
@@ -892,6 +900,7 @@
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);
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs
index f330754..1fe2fdc 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs
@@ -50,6 +50,7 @@
let ra_fmt_layer = tracing_subscriber::fmt::layer()
.with_target(false)
+ .with_ansi(false)
.with_writer(writer)
.with_filter(filter);