Skip to content

Commit ef548b4

Browse files
committed
Improve batching of indexer tasks
1 parent 6cfc926 commit ef548b4

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

crates/ark/src/lsp/main_loop.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -726,30 +726,46 @@ static INDEXER_QUEUE: LazyLock<tokio::sync::mpsc::UnboundedSender<IndexerQueueTa
726726
/// refreshes don't race against each other. The frontend will receive all
727727
/// results in order, ensuring that diagnostics for an outdated version are
728728
/// eventually replaced by the most up-to-date diagnostics.
729+
///
730+
/// Note that this setup will be entirely replaced in the future by Salsa
731+
/// dependencies. Diagnostics refreshes will depend on indexer results in a
732+
/// natural way and they will be cancelled automatically as document updates
733+
/// arrive.
729734
async fn process_indexer_queue(mut rx: mpsc::UnboundedReceiver<IndexerQueueTask>) {
735+
let mut diagnostics_batch = Vec::new();
736+
let mut indexer_batch = Vec::new();
737+
730738
while let Some(task) = rx.recv().await {
731-
// Drain all available tasks
732739
let mut tasks = vec![task];
733-
while let Ok(next_task) = rx.try_recv() {
734-
tasks.push(next_task);
735-
}
736740

737-
// Separate by type
738-
let mut diagnostics_batch = Vec::new();
739-
let mut indexer_batch = Vec::new();
741+
// Process diagnostics at least every 10 iterations if indexer tasks
742+
// keep coming in, so the user gets intermediate diagnostics refreshes
743+
for _ in 0..10 {
744+
while let Ok(task) = rx.try_recv() {
745+
tasks.push(task);
746+
}
740747

741-
for task in tasks {
742-
match task {
743-
IndexerQueueTask::Indexer(indexer_task) => indexer_batch.push(indexer_task),
744-
IndexerQueueTask::Diagnostics(diagnostic_task) => {
745-
diagnostics_batch.push(diagnostic_task)
746-
},
748+
// Separate by type
749+
for task in std::mem::take(&mut tasks) {
750+
match task {
751+
IndexerQueueTask::Indexer(indexer_task) => indexer_batch.push(indexer_task),
752+
IndexerQueueTask::Diagnostics(diagnostic_task) => {
753+
diagnostics_batch.push(diagnostic_task)
754+
},
755+
}
747756
}
757+
758+
// No more indexer tasks, let's do diagnostics
759+
if indexer_batch.is_empty() {
760+
break;
761+
}
762+
763+
// Process indexer tasks first so diagnostics tasks work with an
764+
// up-to-date index
765+
process_indexer_batch(std::mem::take(&mut indexer_batch)).await;
748766
}
749767

750-
// Process indexer tasks first so diagnostics tasks work with an up-to-date index
751-
process_indexer_batch(indexer_batch).await;
752-
process_diagnostics_batch(diagnostics_batch).await;
768+
process_diagnostics_batch(std::mem::take(&mut diagnostics_batch)).await;
753769
}
754770
}
755771

0 commit comments

Comments
 (0)