Limit LSP non-invalidating queries
This commit is contained in:
parent
2b007930a9
commit
e6fb909d89
1 changed files with 40 additions and 0 deletions
|
@ -19,6 +19,7 @@ use project::{InlayHint, ResolveState};
|
||||||
|
|
||||||
use collections::{hash_map, HashMap, HashSet};
|
use collections::{hash_map, HashMap, HashSet};
|
||||||
use language::language_settings::InlayHintSettings;
|
use language::language_settings::InlayHintSettings;
|
||||||
|
use smol::lock::Semaphore;
|
||||||
use sum_tree::Bias;
|
use sum_tree::Bias;
|
||||||
use text::ToOffset;
|
use text::ToOffset;
|
||||||
use util::post_inc;
|
use util::post_inc;
|
||||||
|
@ -29,6 +30,7 @@ pub struct InlayHintCache {
|
||||||
version: usize,
|
version: usize,
|
||||||
pub(super) enabled: bool,
|
pub(super) enabled: bool,
|
||||||
update_tasks: HashMap<ExcerptId, TasksForRanges>,
|
update_tasks: HashMap<ExcerptId, TasksForRanges>,
|
||||||
|
lsp_request_limiter: Arc<Semaphore>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -258,6 +260,7 @@ impl InlayHintCache {
|
||||||
hints: HashMap::default(),
|
hints: HashMap::default(),
|
||||||
update_tasks: HashMap::default(),
|
update_tasks: HashMap::default(),
|
||||||
version: 0,
|
version: 0,
|
||||||
|
lsp_request_limiter: Arc::new(Semaphore::new(MAX_CONCURRENT_LSP_REQUESTS)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,6 +632,7 @@ fn spawn_new_update_tasks(
|
||||||
buffer_snapshot.clone(),
|
buffer_snapshot.clone(),
|
||||||
Arc::clone(&visible_hints),
|
Arc::clone(&visible_hints),
|
||||||
cached_excerpt_hints,
|
cached_excerpt_hints,
|
||||||
|
Arc::clone(&editor.inlay_hint_cache.lsp_request_limiter),
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -733,6 +737,7 @@ fn determine_query_ranges(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MAX_CONCURRENT_LSP_REQUESTS: usize = 5;
|
||||||
const INVISIBLE_RANGES_HINTS_REQUEST_DELAY_MILLIS: u64 = 400;
|
const INVISIBLE_RANGES_HINTS_REQUEST_DELAY_MILLIS: u64 = 400;
|
||||||
|
|
||||||
fn new_update_task(
|
fn new_update_task(
|
||||||
|
@ -742,6 +747,7 @@ fn new_update_task(
|
||||||
buffer_snapshot: BufferSnapshot,
|
buffer_snapshot: BufferSnapshot,
|
||||||
visible_hints: Arc<Vec<Inlay>>,
|
visible_hints: Arc<Vec<Inlay>>,
|
||||||
cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>,
|
cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>,
|
||||||
|
lsp_request_limiter: Arc<Semaphore>,
|
||||||
cx: &mut ViewContext<'_, '_, Editor>,
|
cx: &mut ViewContext<'_, '_, Editor>,
|
||||||
) -> Task<()> {
|
) -> Task<()> {
|
||||||
cx.spawn(|editor, mut cx| async move {
|
cx.spawn(|editor, mut cx| async move {
|
||||||
|
@ -756,6 +762,7 @@ fn new_update_task(
|
||||||
query,
|
query,
|
||||||
invalidate,
|
invalidate,
|
||||||
range,
|
range,
|
||||||
|
Arc::clone(&lsp_request_limiter),
|
||||||
closure_cx.clone(),
|
closure_cx.clone(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -826,10 +833,41 @@ async fn fetch_and_update_hints(
|
||||||
query: ExcerptQuery,
|
query: ExcerptQuery,
|
||||||
invalidate: bool,
|
invalidate: bool,
|
||||||
fetch_range: Range<language::Anchor>,
|
fetch_range: Range<language::Anchor>,
|
||||||
|
lsp_request_limiter: Arc<Semaphore>,
|
||||||
mut cx: gpui::AsyncAppContext,
|
mut cx: gpui::AsyncAppContext,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
let (lsp_request_guard, got_throttled) = if query.invalidate.should_invalidate() {
|
||||||
|
(None, false)
|
||||||
|
} else {
|
||||||
|
match lsp_request_limiter.try_acquire() {
|
||||||
|
Some(guard) => (Some(guard), false),
|
||||||
|
None => (Some(lsp_request_limiter.acquire().await), true),
|
||||||
|
}
|
||||||
|
};
|
||||||
let inlay_hints_fetch_task = editor
|
let inlay_hints_fetch_task = editor
|
||||||
.update(&mut cx, |editor, cx| {
|
.update(&mut cx, |editor, cx| {
|
||||||
|
if got_throttled {
|
||||||
|
if let Some((_, _, current_visible_range)) = editor
|
||||||
|
.excerpt_visible_offsets(None, cx)
|
||||||
|
.remove(&query.excerpt_id)
|
||||||
|
{
|
||||||
|
let visible_offset_length = current_visible_range.len();
|
||||||
|
let double_visible_range = current_visible_range
|
||||||
|
.start
|
||||||
|
.saturating_sub(visible_offset_length)
|
||||||
|
..current_visible_range
|
||||||
|
.end
|
||||||
|
.saturating_add(visible_offset_length)
|
||||||
|
.min(buffer_snapshot.len());
|
||||||
|
if !double_visible_range
|
||||||
|
.contains(&fetch_range.start.to_offset(&buffer_snapshot))
|
||||||
|
&& !double_visible_range
|
||||||
|
.contains(&fetch_range.end.to_offset(&buffer_snapshot))
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
editor
|
editor
|
||||||
.buffer()
|
.buffer()
|
||||||
.read(cx)
|
.read(cx)
|
||||||
|
@ -847,6 +885,8 @@ async fn fetch_and_update_hints(
|
||||||
Some(task) => task.await.context("inlay hint fetch task")?,
|
Some(task) => task.await.context("inlay hint fetch task")?,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
drop(lsp_request_guard);
|
||||||
|
|
||||||
let background_task_buffer_snapshot = buffer_snapshot.clone();
|
let background_task_buffer_snapshot = buffer_snapshot.clone();
|
||||||
let backround_fetch_range = fetch_range.clone();
|
let backround_fetch_range = fetch_range.clone();
|
||||||
let new_update = cx
|
let new_update = cx
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue