mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
Auto merge of #17850 - Veykril:rust-analyzer-crate, r=Veykril
internal: Reply to requests with defaults when vfs is still loading There is no reason for us to hit the database with queries when we certainly haven't reached a stable state yet. Instead we just reply with default request results until we are in a state where we can do meaningful work. This should save us from wasting resources while starting up at worst, and at best save us from creating query and interning entries that are non-meaningful which ultimately just end up wasting memory.
This commit is contained in:
commit
59c6eae5cc
5 changed files with 71 additions and 27 deletions
|
@ -4,7 +4,7 @@ exclude = ["crates/proc-macro-srv/proc-macro-test/imp"]
|
|||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
rust-version = "1.78"
|
||||
rust-version = "1.80"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
authors = ["rust-analyzer team"]
|
||||
|
|
|
@ -97,16 +97,45 @@ impl RequestDispatcher<'_> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Dispatches a non-latency-sensitive request onto the thread pool.
|
||||
/// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not
|
||||
/// ready this will return a default constructed [`R::Result`].
|
||||
pub(crate) fn on<const ALLOW_RETRYING: bool, R>(
|
||||
&mut self,
|
||||
f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>,
|
||||
) -> &mut Self
|
||||
where
|
||||
R: lsp_types::request::Request + 'static,
|
||||
R::Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug,
|
||||
R::Result: Serialize,
|
||||
R: lsp_types::request::Request<
|
||||
Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug,
|
||||
Result: Serialize + Default,
|
||||
> + 'static,
|
||||
{
|
||||
if !self.global_state.vfs_done {
|
||||
if let Some(lsp_server::Request { id, .. }) =
|
||||
self.req.take_if(|it| it.method == R::METHOD)
|
||||
{
|
||||
self.global_state.respond(lsp_server::Response::new_ok(id, R::Result::default()));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
self.on_with_thread_intent::<true, ALLOW_RETRYING, R>(ThreadIntent::Worker, f)
|
||||
}
|
||||
|
||||
/// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not
|
||||
/// ready this will return the parameter as is.
|
||||
pub(crate) fn on_identity<const ALLOW_RETRYING: bool, R, Params>(
|
||||
&mut self,
|
||||
f: fn(GlobalStateSnapshot, Params) -> anyhow::Result<R::Result>,
|
||||
) -> &mut Self
|
||||
where
|
||||
R: lsp_types::request::Request<Params = Params, Result = Params> + 'static,
|
||||
Params: Serialize + DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug,
|
||||
{
|
||||
if !self.global_state.vfs_done {
|
||||
if let Some((request, params, _)) = self.parse::<R>() {
|
||||
self.global_state.respond(lsp_server::Response::new_ok(request.id, ¶ms))
|
||||
}
|
||||
return self;
|
||||
}
|
||||
self.on_with_thread_intent::<true, ALLOW_RETRYING, R>(ThreadIntent::Worker, f)
|
||||
}
|
||||
|
||||
|
@ -198,11 +227,7 @@ impl RequestDispatcher<'_> {
|
|||
R: lsp_types::request::Request,
|
||||
R::Params: DeserializeOwned + fmt::Debug,
|
||||
{
|
||||
let req = match &self.req {
|
||||
Some(req) if req.method == R::METHOD => self.req.take()?,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let req = self.req.take_if(|it| it.method == R::METHOD)?;
|
||||
let res = crate::from_json(R::METHOD, &req.params);
|
||||
match res {
|
||||
Ok(params) => {
|
||||
|
|
|
@ -61,7 +61,7 @@ impl Request for FetchDependencyList {
|
|||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FetchDependencyListParams {}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FetchDependencyListResult {
|
||||
pub crates: Vec<CrateInfoResult>,
|
||||
|
@ -194,7 +194,7 @@ pub struct TestItem {
|
|||
pub runnable: Option<Runnable>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DiscoverTestResults {
|
||||
pub tests: Vec<TestItem>,
|
||||
|
@ -690,6 +690,12 @@ pub enum ExternalDocsResponse {
|
|||
WithLocal(ExternalDocsPair),
|
||||
}
|
||||
|
||||
impl Default for ExternalDocsResponse {
|
||||
fn default() -> Self {
|
||||
ExternalDocsResponse::Simple(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ExternalDocsPair {
|
||||
|
|
|
@ -173,8 +173,10 @@ impl GlobalState {
|
|||
}
|
||||
|
||||
if self.config.discover_workspace_config().is_none() {
|
||||
let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
|
||||
self.fetch_workspaces_queue.request_op("startup".to_owned(), req);
|
||||
self.fetch_workspaces_queue.request_op(
|
||||
"startup".to_owned(),
|
||||
FetchWorkspaceRequest { path: None, force_crate_graph_reload: false },
|
||||
);
|
||||
if let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) =
|
||||
self.fetch_workspaces_queue.should_start_op()
|
||||
{
|
||||
|
@ -545,6 +547,10 @@ impl GlobalState {
|
|||
let snapshot = self.snapshot();
|
||||
self.task_pool.handle.spawn_with_sender(ThreadIntent::LatencySensitive, {
|
||||
let subscriptions = subscriptions.clone();
|
||||
// Do not fetch semantic diagnostics (and populate query results) if we haven't even
|
||||
// loaded the initial workspace yet.
|
||||
let fetch_semantic =
|
||||
self.vfs_done && self.fetch_workspaces_queue.last_op_result().is_some();
|
||||
move |sender| {
|
||||
let diags = fetch_native_diagnostics(
|
||||
&snapshot,
|
||||
|
@ -556,15 +562,19 @@ impl GlobalState {
|
|||
.send(Task::Diagnostics(DiagnosticsTaskKind::Syntax(generation, diags)))
|
||||
.unwrap();
|
||||
|
||||
let diags = fetch_native_diagnostics(
|
||||
&snapshot,
|
||||
subscriptions,
|
||||
slice,
|
||||
NativeDiagnosticsFetchKind::Semantic,
|
||||
);
|
||||
sender
|
||||
.send(Task::Diagnostics(DiagnosticsTaskKind::Semantic(generation, diags)))
|
||||
.unwrap();
|
||||
if fetch_semantic {
|
||||
let diags = fetch_native_diagnostics(
|
||||
&snapshot,
|
||||
subscriptions,
|
||||
slice,
|
||||
NativeDiagnosticsFetchKind::Semantic,
|
||||
);
|
||||
sender
|
||||
.send(Task::Diagnostics(DiagnosticsTaskKind::Semantic(
|
||||
generation, diags,
|
||||
)))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
start = end;
|
||||
|
@ -572,6 +582,9 @@ impl GlobalState {
|
|||
}
|
||||
|
||||
fn update_tests(&mut self) {
|
||||
if !self.vfs_done {
|
||||
return;
|
||||
}
|
||||
let db = self.analysis_host.raw_database();
|
||||
let subscriptions = self
|
||||
.mem_docs
|
||||
|
@ -1052,9 +1065,9 @@ impl GlobalState {
|
|||
.on::<NO_RETRY, lsp_request::GotoImplementation>(handlers::handle_goto_implementation)
|
||||
.on::<NO_RETRY, lsp_request::GotoTypeDefinition>(handlers::handle_goto_type_definition)
|
||||
.on::<NO_RETRY, lsp_request::InlayHintRequest>(handlers::handle_inlay_hints)
|
||||
.on::<NO_RETRY, lsp_request::InlayHintResolveRequest>(handlers::handle_inlay_hints_resolve)
|
||||
.on_identity::<NO_RETRY, lsp_request::InlayHintResolveRequest, _>(handlers::handle_inlay_hints_resolve)
|
||||
.on::<NO_RETRY, lsp_request::CodeLensRequest>(handlers::handle_code_lens)
|
||||
.on::<NO_RETRY, lsp_request::CodeLensResolve>(handlers::handle_code_lens_resolve)
|
||||
.on_identity::<NO_RETRY, lsp_request::CodeLensResolve, _>(handlers::handle_code_lens_resolve)
|
||||
.on::<NO_RETRY, lsp_request::PrepareRenameRequest>(handlers::handle_prepare_rename)
|
||||
.on::<NO_RETRY, lsp_request::Rename>(handlers::handle_rename)
|
||||
.on::<NO_RETRY, lsp_request::References>(handlers::handle_references)
|
||||
|
@ -1081,7 +1094,7 @@ impl GlobalState {
|
|||
.on::<NO_RETRY, lsp_ext::Runnables>(handlers::handle_runnables)
|
||||
.on::<NO_RETRY, lsp_ext::RelatedTests>(handlers::handle_related_tests)
|
||||
.on::<NO_RETRY, lsp_ext::CodeActionRequest>(handlers::handle_code_action)
|
||||
.on::<RETRY, lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
|
||||
.on_identity::<RETRY, lsp_ext::CodeActionResolveRequest, _>(handlers::handle_code_action_resolve)
|
||||
.on::<NO_RETRY, lsp_ext::HoverRequest>(handlers::handle_hover)
|
||||
.on::<NO_RETRY, lsp_ext::ExternalDocs>(handlers::handle_open_docs)
|
||||
.on::<NO_RETRY, lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!---
|
||||
lsp/ext.rs hash: e92e1f12229b0071
|
||||
lsp/ext.rs hash: 3429c08745984b3d
|
||||
|
||||
If you need to change the above hash to make the test pass, please check if you
|
||||
need to adjust this doc as well and ping this issue:
|
||||
|
|
Loading…
Reference in a new issue