[ty] Limit the returned completions to reduce lag (#22240)

This commit is contained in:
Micha Reiser
2025-12-29 10:16:32 +01:00
committed by GitHub
parent 6776543b62
commit 8efa14ae1b
5 changed files with 24 additions and 6 deletions

View File

@@ -21,6 +21,9 @@ pub fn all_symbols<'db>(
return Vec::new();
}
let all_symbols_span = tracing::debug_span!("all_symbols");
let _span = all_symbols_span.enter();
let typing_extensions = ModuleName::new_static("typing_extensions").unwrap();
let is_typing_extensions_available = importing_from.is_stub(db)
|| resolve_real_shadowable_module(db, importing_from, &typing_extensions).is_some();
@@ -29,6 +32,7 @@ pub fn all_symbols<'db>(
{
let modules = all_modules(db);
let db = db.dyn_clone();
let all_symbols_span = &all_symbols_span;
let results = &results;
let query = &query;
@@ -39,6 +43,7 @@ pub fn all_symbols<'db>(
let Some(file) = module.file(&*db) else {
continue;
};
// By convention, modules starting with an underscore
// are generally considered unexported. However, we
// should consider first party modules fair game.
@@ -59,6 +64,9 @@ pub fn all_symbols<'db>(
continue;
}
s.spawn(move |_| {
let symbols_for_file_span = tracing::debug_span!(parent: all_symbols_span, "symbols_for_file_global_only", ?file);
let _entered = symbols_for_file_span.entered();
if query.is_match_symbol_name(module.name(&*db)) {
results.lock().unwrap().push(AllSymbolInfo {
symbol: None,

View File

@@ -117,6 +117,9 @@ impl<'db> Completions<'db> {
self.items.sort_by(|c1, c2| self.context.compare(c1, c2));
self.items
.dedup_by(|c1, c2| (&c1.name, c1.module_name) == (&c2.name, c2.module_name));
// A user should refine its completion request if the searched symbol doesn't appear in the first 1k results.
// Serializing/deserializing 1k completions can be expensive and result in noticeable lag.
self.items.truncate(1000);
self.items
}

View File

@@ -10,6 +10,9 @@ pub fn workspace_symbols(db: &dyn Db, query: &str) -> Vec<WorkspaceSymbolInfo> {
return Vec::new();
}
let workspace_symbols_span = tracing::debug_span!("workspace_symbols");
let _span = workspace_symbols_span.enter();
let project = db.project();
let query = QueryPattern::fuzzy(query);
@@ -20,12 +23,16 @@ pub fn workspace_symbols(db: &dyn Db, query: &str) -> Vec<WorkspaceSymbolInfo> {
let files = &files;
let results = &results;
let query = &query;
let workspace_symbols_span = &workspace_symbols_span;
rayon::scope(move |s| {
// For each file, extract symbols and add them to results
for file in files.iter() {
let db = db.dyn_clone();
s.spawn(move |_| {
let symbols_for_file_span = tracing::debug_span!(parent: workspace_symbols_span, "symbols_for_file", ?file);
let _entered = symbols_for_file_span.entered();
for (_, symbol) in symbols_for_file(&*db, *file).search(query) {
// It seems like we could do better here than
// locking `results` for every single symbol,

View File

@@ -224,7 +224,7 @@ where
// Test again if the request was cancelled since it was scheduled on the background task
// and, if so, return early
if cancellation_token.is_cancelled() {
tracing::trace!(
tracing::debug!(
"Ignoring request id={id} method={} because it was cancelled",
R::METHOD
);
@@ -291,7 +291,7 @@ where
// Test again if the request was cancelled since it was scheduled on the background task
// and, if so, return early
if cancellation_token.is_cancelled() {
tracing::trace!(
tracing::debug!(
"Ignoring request id={id} method={} because it was cancelled",
R::METHOD
);
@@ -325,14 +325,14 @@ fn panic_response<R>(
// If the query supports retry, re-queue the request.
// The query is still likely to succeed if the user modified any other document.
if let Some(request) = request {
tracing::trace!(
tracing::debug!(
"request id={} method={} was cancelled by salsa, re-queueing for retry",
request.id,
request.method
);
client.retry(request);
} else {
tracing::trace!(
tracing::debug!(
"request id={} was cancelled by salsa, sending content modified",
id
);

View File

@@ -110,11 +110,11 @@ impl Server {
.complete(&response.id)
{
let duration = start_time.elapsed();
tracing::trace!(name: "message response", method, %response.id, duration = format_args!("{:0.2?}", duration));
tracing::debug!(name: "message response", method, %response.id, duration = format_args!("{:0.2?}", duration));
self.connection.sender.send(Message::Response(response))?;
} else {
tracing::trace!(
tracing::debug!(
"Ignoring response for canceled request id={}",
response.id
);