
Previously, we were: - cancelling previous requests only after the latest one has completed - always running the debounced documentation resolution to completion, even when we had no need for it. In this commit, we drop the ongoing completion requests as soon as the new one is fired. Fixes #5166 Release Notes: - Improved performance and reliability of completions in large Typescript projects Co-authored-by: Bennet Bo <bennet@zed.dev>
45 lines
1.2 KiB
Rust
45 lines
1.2 KiB
Rust
use std::time::Duration;
|
|
|
|
use futures::{channel::oneshot, FutureExt};
|
|
use gpui::{Task, ViewContext};
|
|
|
|
use crate::Editor;
|
|
|
|
pub struct DebouncedDelay {
|
|
task: Option<Task<()>>,
|
|
cancel_channel: Option<oneshot::Sender<()>>,
|
|
}
|
|
|
|
impl DebouncedDelay {
|
|
pub fn new() -> DebouncedDelay {
|
|
DebouncedDelay {
|
|
task: None,
|
|
cancel_channel: None,
|
|
}
|
|
}
|
|
|
|
pub fn fire_new<F>(&mut self, delay: Duration, cx: &mut ViewContext<Editor>, func: F)
|
|
where
|
|
F: 'static + Send + FnOnce(&mut Editor, &mut ViewContext<Editor>) -> Task<()>,
|
|
{
|
|
if let Some(channel) = self.cancel_channel.take() {
|
|
_ = channel.send(());
|
|
}
|
|
|
|
let (sender, mut receiver) = oneshot::channel::<()>();
|
|
self.cancel_channel = Some(sender);
|
|
|
|
drop(self.task.take());
|
|
self.task = Some(cx.spawn(move |model, mut cx| async move {
|
|
let mut timer = cx.background_executor().timer(delay).fuse();
|
|
futures::select_biased! {
|
|
_ = receiver => return,
|
|
_ = timer => {}
|
|
}
|
|
|
|
if let Ok(task) = model.update(&mut cx, |project, cx| (func)(project, cx)) {
|
|
task.await;
|
|
}
|
|
}));
|
|
}
|
|
}
|