Remove query ranges for failed inlay hint requests

This commit is contained in:
Kirill Bulatov 2023-08-26 03:52:52 +03:00
parent 8ddee0e58d
commit 2b007930a9

View file

@ -108,17 +108,23 @@ impl TasksForRanges {
updated_ranges.before_visible = updated_ranges updated_ranges.before_visible = updated_ranges
.before_visible .before_visible
.into_iter() .into_iter()
.flat_map(|query_range| self.remove_cached_ranges(buffer_snapshot, query_range)) .flat_map(|query_range| {
self.remove_cached_ranges_from_query(buffer_snapshot, query_range)
})
.collect(); .collect();
updated_ranges.visible = updated_ranges updated_ranges.visible = updated_ranges
.visible .visible
.into_iter() .into_iter()
.flat_map(|query_range| self.remove_cached_ranges(buffer_snapshot, query_range)) .flat_map(|query_range| {
self.remove_cached_ranges_from_query(buffer_snapshot, query_range)
})
.collect(); .collect();
updated_ranges.after_visible = updated_ranges updated_ranges.after_visible = updated_ranges
.after_visible .after_visible
.into_iter() .into_iter()
.flat_map(|query_range| self.remove_cached_ranges(buffer_snapshot, query_range)) .flat_map(|query_range| {
self.remove_cached_ranges_from_query(buffer_snapshot, query_range)
})
.collect(); .collect();
updated_ranges updated_ranges
} }
@ -134,7 +140,7 @@ impl TasksForRanges {
} }
} }
fn remove_cached_ranges( fn remove_cached_ranges_from_query(
&mut self, &mut self,
buffer_snapshot: &BufferSnapshot, buffer_snapshot: &BufferSnapshot,
query_range: Range<language::Anchor>, query_range: Range<language::Anchor>,
@ -196,6 +202,52 @@ impl TasksForRanges {
ranges_to_query ranges_to_query
} }
fn remove_from_cached_ranges(
&mut self,
buffer: &BufferSnapshot,
range_to_remove: Range<language::Anchor>,
) {
self.sorted_ranges = self
.sorted_ranges
.drain(..)
.filter_map(|mut cached_range| {
if cached_range.start.cmp(&range_to_remove.end, buffer).is_gt()
|| cached_range.end.cmp(&range_to_remove.start, buffer).is_lt()
{
Some(vec![cached_range])
} else if cached_range
.start
.cmp(&range_to_remove.start, buffer)
.is_ge()
&& cached_range.end.cmp(&range_to_remove.end, buffer).is_le()
{
None
} else if range_to_remove
.start
.cmp(&cached_range.start, buffer)
.is_ge()
&& range_to_remove.end.cmp(&cached_range.end, buffer).is_le()
{
Some(vec![
cached_range.start..range_to_remove.start,
range_to_remove.end..cached_range.end,
])
} else if cached_range
.start
.cmp(&range_to_remove.start, buffer)
.is_ge()
{
cached_range.start = range_to_remove.end;
Some(vec![cached_range])
} else {
cached_range.end = range_to_remove.start;
Some(vec![cached_range])
}
})
.flatten()
.collect();
}
} }
impl InlayHintCache { impl InlayHintCache {
@ -692,7 +744,8 @@ fn new_update_task(
cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>, cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>,
cx: &mut ViewContext<'_, '_, Editor>, cx: &mut ViewContext<'_, '_, Editor>,
) -> Task<()> { ) -> Task<()> {
cx.spawn(|editor, cx| async move { cx.spawn(|editor, mut cx| async move {
let closure_cx = cx.clone();
let fetch_and_update_hints = |invalidate, range| { let fetch_and_update_hints = |invalidate, range| {
fetch_and_update_hints( fetch_and_update_hints(
editor.clone(), editor.clone(),
@ -703,37 +756,62 @@ fn new_update_task(
query, query,
invalidate, invalidate,
range, range,
cx.clone(), closure_cx.clone(),
) )
}; };
let visible_range_update_results = let visible_range_update_results = future::join_all(query_ranges.visible.into_iter().map(
future::join_all(query_ranges.visible.into_iter().map(|visible_range| { |visible_range| async move {
fetch_and_update_hints(query.invalidate.should_invalidate(), visible_range) (
})) visible_range.clone(),
.await; fetch_and_update_hints(query.invalidate.should_invalidate(), visible_range)
for result in visible_range_update_results { .await,
)
},
))
.await;
let hint_delay = cx.background().timer(Duration::from_millis(
INVISIBLE_RANGES_HINTS_REQUEST_DELAY_MILLIS,
));
let mut query_range_failed = |range: Range<language::Anchor>, e: anyhow::Error| {
error!("inlay hint update task for range {range:?} failed: {e:#}");
editor
.update(&mut cx, |editor, _| {
if let Some(task_ranges) = editor
.inlay_hint_cache
.update_tasks
.get_mut(&query.excerpt_id)
{
task_ranges.remove_from_cached_ranges(&buffer_snapshot, range);
}
})
.ok()
};
for (range, result) in visible_range_update_results {
if let Err(e) = result { if let Err(e) = result {
error!("visible range inlay hint update task failed: {e:#}"); query_range_failed(range, e);
} }
} }
cx.background() hint_delay.await;
.timer(Duration::from_millis(
INVISIBLE_RANGES_HINTS_REQUEST_DELAY_MILLIS,
))
.await;
let invisible_range_update_results = future::join_all( let invisible_range_update_results = future::join_all(
query_ranges query_ranges
.before_visible .before_visible
.into_iter() .into_iter()
.chain(query_ranges.after_visible.into_iter()) .chain(query_ranges.after_visible.into_iter())
.map(|invisible_range| fetch_and_update_hints(false, invisible_range)), .map(|invisible_range| async move {
(
invisible_range.clone(),
fetch_and_update_hints(false, invisible_range).await,
)
}),
) )
.await; .await;
for result in invisible_range_update_results { for (range, result) in invisible_range_update_results {
if let Err(e) = result { if let Err(e) = result {
error!("invisible range inlay hint update task failed: {e:#}"); query_range_failed(range, e);
} }
} }
}) })