mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 16:19:12 -05:00
perf(lsp): cancel ts requests on future drop (#21387)
When an old request is obsoleted while the user is typing, the client will say so to the server and tower-lsp will drop the future associated with that request. This wires that up to the ts server by having any request's token be cancelled when the surrounding state is dropped.
This commit is contained in:
parent
6718be87c8
commit
595a2be024
1 changed files with 19 additions and 2 deletions
|
@ -231,8 +231,12 @@ impl TsServer {
|
||||||
start(&mut ts_runtime, false).unwrap();
|
start(&mut ts_runtime, false).unwrap();
|
||||||
started = true;
|
started = true;
|
||||||
}
|
}
|
||||||
let value = request(&mut ts_runtime, state_snapshot, req, token);
|
let value =
|
||||||
if tx.send(value).is_err() {
|
request(&mut ts_runtime, state_snapshot, req, token.clone());
|
||||||
|
let was_sent = tx.send(value).is_ok();
|
||||||
|
// Don't print the send error if the token is cancelled, it's expected
|
||||||
|
// to fail in that case and this commonly occurs.
|
||||||
|
if !was_sent && !token.is_cancelled() {
|
||||||
lsp_warn!("Unable to send result to client.");
|
lsp_warn!("Unable to send result to client.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -968,11 +972,24 @@ impl TsServer {
|
||||||
where
|
where
|
||||||
R: de::DeserializeOwned,
|
R: de::DeserializeOwned,
|
||||||
{
|
{
|
||||||
|
// When an LSP request is cancelled by the client, the future this is being
|
||||||
|
// executed under and any local variables here will be dropped at the next
|
||||||
|
// await point. To pass on that cancellation to the TS thread, we make this
|
||||||
|
// wrapper which cancels the request's token on drop.
|
||||||
|
struct DroppableToken(CancellationToken);
|
||||||
|
impl Drop for DroppableToken {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.0.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let token = token.child_token();
|
||||||
|
let droppable_token = DroppableToken(token.clone());
|
||||||
let (tx, rx) = oneshot::channel::<Result<Value, AnyError>>();
|
let (tx, rx) = oneshot::channel::<Result<Value, AnyError>>();
|
||||||
if self.sender.send((req, snapshot, tx, token)).is_err() {
|
if self.sender.send((req, snapshot, tx, token)).is_err() {
|
||||||
return Err(anyhow!("failed to send request to tsc thread"));
|
return Err(anyhow!("failed to send request to tsc thread"));
|
||||||
}
|
}
|
||||||
let value = rx.await??;
|
let value = rx.await??;
|
||||||
|
drop(droppable_token);
|
||||||
Ok(serde_json::from_value::<R>(value)?)
|
Ok(serde_json::from_value::<R>(value)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue