1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 15:49:44 -05:00

fix(lsp): force shutdown after a timeout (#21251)

This commit is contained in:
Nayeem Rahman 2023-11-22 04:08:48 +00:00 committed by GitHub
parent a8c24d2a8b
commit 64997cce6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 7 deletions

View file

@ -30,6 +30,7 @@ use std::env;
use std::fmt::Write as _;
use std::path::PathBuf;
use std::sync::Arc;
use tokio_util::sync::CancellationToken;
use tower_lsp::jsonrpc::Error as LspError;
use tower_lsp::jsonrpc::Result as LspResult;
use tower_lsp::lsp_types::request::*;
@ -156,7 +157,7 @@ impl LspNpmConfigHash {
}
#[derive(Debug, Clone)]
pub struct LanguageServer(Arc<tokio::sync::RwLock<Inner>>);
pub struct LanguageServer(Arc<tokio::sync::RwLock<Inner>>, CancellationToken);
#[derive(Debug)]
pub struct StateNpmSnapshot {
@ -226,8 +227,11 @@ pub struct Inner {
}
impl LanguageServer {
pub fn new(client: Client) -> Self {
Self(Arc::new(tokio::sync::RwLock::new(Inner::new(client))))
pub fn new(client: Client, token: CancellationToken) -> Self {
Self(
Arc::new(tokio::sync::RwLock::new(Inner::new(client))),
token,
)
}
/// Similar to `deno cache` on the command line, where modules will be cached
@ -3216,6 +3220,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
}
async fn shutdown(&self) -> LspResult<()> {
self.1.cancel();
self.0.write().await.shutdown().await
}

View file

@ -1,6 +1,8 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError;
use deno_core::unsync::spawn;
use tokio_util::sync::CancellationToken;
use tower_lsp::LspService;
use tower_lsp::Server;
@ -39,8 +41,12 @@ pub async fn start() -> Result<(), AnyError> {
let stdin = tokio::io::stdin();
let stdout = tokio::io::stdout();
let token = CancellationToken::new();
let builder = LspService::build(|client| {
language_server::LanguageServer::new(client::Client::from_tower(client))
language_server::LanguageServer::new(
client::Client::from_tower(client),
token.clone(),
)
})
// TODO(nayeemrmn): The extension has replaced this with the `deno.cache`
// command as of vscode_deno 3.21.0 / 2023.09.05. Remove this eventually.
@ -81,7 +87,18 @@ pub async fn start() -> Result<(), AnyError> {
let (service, socket) = builder.finish();
Server::new(stdin, stdout, socket).serve(service).await;
// TODO(nayeemrmn): This cancellation token is a workaround for
// https://github.com/denoland/deno/issues/20700. Remove when
// https://github.com/ebkalderon/tower-lsp/issues/399 is fixed.
// Force end the server 8 seconds after receiving a shutdown request.
tokio::select! {
biased;
_ = Server::new(stdin, stdout, socket).serve(service) => {}
_ = spawn(async move {
token.cancelled().await;
tokio::time::sleep(std::time::Duration::from_secs(8)).await;
}) => {}
}
Ok(())
}

View file

@ -61,8 +61,10 @@ impl ReplLanguageServer {
super::logging::set_lsp_log_level(log::Level::Debug);
super::logging::set_lsp_warn_level(log::Level::Debug);
let language_server =
super::language_server::LanguageServer::new(Client::new_for_repl());
let language_server = super::language_server::LanguageServer::new(
Client::new_for_repl(),
Default::default(),
);
let cwd_uri = get_cwd_uri()?;