From cb7f56fb206ba5ce686061e2a49a7ddc3e22954e Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Tue, 8 Apr 2025 08:33:30 +0200 Subject: [PATCH] [red-knot] Don't use latency-sensitive for handlers (#17227) ## Summary The priority latency-sensitive is reserved for actions that need to run immediately because they would otherwise block the user's action. An example of this is a format request. VS code blocks the editor until the save action is complete. That's why formatting a document is very sensitive to delays and it's important that we always have a worker thread available to run a format request *immediately*. Another example are code completions, where it's important that they appear immediately when the user types. On the other hand, showing diagnostics, hover, or inlay hints has high priority but users are used that the editor takes a few ms to compute the overlay. Computing this information can also be expensive (e.g. find all references), blocking the worker for quiet some time (a few 100ms). That's why it's important that those requests don't clog the sensitive worker threads. --- crates/red_knot_server/src/server/api.rs | 26 +++++++++---------- .../src/server/schedule/task.rs | 3 ++- crates/ruff_server/src/server/api.rs | 12 +++------ .../ruff_server/src/server/schedule/task.rs | 4 ++- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/crates/red_knot_server/src/server/api.rs b/crates/red_knot_server/src/server/api.rs index 8a659290cc..f62d155a4e 100644 --- a/crates/red_knot_server/src/server/api.rs +++ b/crates/red_knot_server/src/server/api.rs @@ -20,21 +20,19 @@ pub(super) fn request<'a>(req: server::Request) -> Task<'a> { let id = req.id.clone(); match req.method.as_str() { - request::DocumentDiagnosticRequestHandler::METHOD => { - background_request_task::( - req, - BackgroundSchedule::LatencySensitive, - ) + request::DocumentDiagnosticRequestHandler::METHOD => background_request_task::< + request::DocumentDiagnosticRequestHandler, + >( + req, BackgroundSchedule::Worker + ), + request::GotoTypeDefinitionRequestHandler::METHOD => background_request_task::< + request::GotoTypeDefinitionRequestHandler, + >( + req, BackgroundSchedule::Worker + ), + request::HoverRequestHandler::METHOD => { + background_request_task::(req, BackgroundSchedule::Worker) } - request::GotoTypeDefinitionRequestHandler::METHOD => { - background_request_task::( - req, - BackgroundSchedule::LatencySensitive, - ) - } - request::HoverRequestHandler::METHOD => background_request_task::< - request::HoverRequestHandler, - >(req, BackgroundSchedule::LatencySensitive), method => { tracing::warn!("Received request {method} which does not have a handler"); diff --git a/crates/red_knot_server/src/server/schedule/task.rs b/crates/red_knot_server/src/server/schedule/task.rs index 3cc49d378d..d269c1edb5 100644 --- a/crates/red_knot_server/src/server/schedule/task.rs +++ b/crates/red_knot_server/src/server/schedule/task.rs @@ -20,9 +20,10 @@ pub(in crate::server) enum BackgroundSchedule { #[expect(dead_code)] Fmt, /// The task should be run on the general high-priority background - /// thread. + /// thread. Reserved for actions caused by the user typing (e.g.syntax highlighting). LatencySensitive, /// The task should be run on a regular-priority background thread. + /// The default for any request that isn't in the critical path of the user typing. #[default] Worker, } diff --git a/crates/ruff_server/src/server/api.rs b/crates/ruff_server/src/server/api.rs index 96414f1840..7b95ea68e3 100644 --- a/crates/ruff_server/src/server/api.rs +++ b/crates/ruff_server/src/server/api.rs @@ -29,18 +29,14 @@ pub(super) fn request<'a>(req: server::Request) -> Task<'a> { let id = req.id.clone(); match req.method.as_str() { - request::CodeActions::METHOD => background_request_task::( - req, - BackgroundSchedule::LatencySensitive, - ), + request::CodeActions::METHOD => { + background_request_task::(req, BackgroundSchedule::Worker) + } request::CodeActionResolve::METHOD => { background_request_task::(req, BackgroundSchedule::Worker) } request::DocumentDiagnostic::METHOD => { - background_request_task::( - req, - BackgroundSchedule::LatencySensitive, - ) + background_request_task::(req, BackgroundSchedule::Worker) } request::ExecuteCommand::METHOD => local_request_task::(req), request::Format::METHOD => { diff --git a/crates/ruff_server/src/server/schedule/task.rs b/crates/ruff_server/src/server/schedule/task.rs index fdba5e3991..e34b22ed69 100644 --- a/crates/ruff_server/src/server/schedule/task.rs +++ b/crates/ruff_server/src/server/schedule/task.rs @@ -19,9 +19,11 @@ pub(in crate::server) enum BackgroundSchedule { /// for formatting actions. This is a high priority thread. Fmt, /// The task should be run on the general high-priority background - /// thread. + /// thread. Reserved for actions caused by the user typing (e.g.syntax highlighting). + #[expect(dead_code)] LatencySensitive, /// The task should be run on a regular-priority background thread. + /// The default for any request that isn't in the critical path of the user typing. #[default] Worker, }