mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
fix(lsp): force shutdown after a timeout (#21251)
This commit is contained in:
parent
a8c24d2a8b
commit
64997cce6a
3 changed files with 31 additions and 7 deletions
|
@ -30,6 +30,7 @@ use std::env;
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use tokio_util::sync::CancellationToken;
|
||||||
use tower_lsp::jsonrpc::Error as LspError;
|
use tower_lsp::jsonrpc::Error as LspError;
|
||||||
use tower_lsp::jsonrpc::Result as LspResult;
|
use tower_lsp::jsonrpc::Result as LspResult;
|
||||||
use tower_lsp::lsp_types::request::*;
|
use tower_lsp::lsp_types::request::*;
|
||||||
|
@ -156,7 +157,7 @@ impl LspNpmConfigHash {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct LanguageServer(Arc<tokio::sync::RwLock<Inner>>);
|
pub struct LanguageServer(Arc<tokio::sync::RwLock<Inner>>, CancellationToken);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StateNpmSnapshot {
|
pub struct StateNpmSnapshot {
|
||||||
|
@ -226,8 +227,11 @@ pub struct Inner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LanguageServer {
|
impl LanguageServer {
|
||||||
pub fn new(client: Client) -> Self {
|
pub fn new(client: Client, token: CancellationToken) -> Self {
|
||||||
Self(Arc::new(tokio::sync::RwLock::new(Inner::new(client))))
|
Self(
|
||||||
|
Arc::new(tokio::sync::RwLock::new(Inner::new(client))),
|
||||||
|
token,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Similar to `deno cache` on the command line, where modules will be cached
|
/// 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<()> {
|
async fn shutdown(&self) -> LspResult<()> {
|
||||||
|
self.1.cancel();
|
||||||
self.0.write().await.shutdown().await
|
self.0.write().await.shutdown().await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::unsync::spawn;
|
||||||
|
use tokio_util::sync::CancellationToken;
|
||||||
use tower_lsp::LspService;
|
use tower_lsp::LspService;
|
||||||
use tower_lsp::Server;
|
use tower_lsp::Server;
|
||||||
|
|
||||||
|
@ -39,8 +41,12 @@ pub async fn start() -> Result<(), AnyError> {
|
||||||
let stdin = tokio::io::stdin();
|
let stdin = tokio::io::stdin();
|
||||||
let stdout = tokio::io::stdout();
|
let stdout = tokio::io::stdout();
|
||||||
|
|
||||||
|
let token = CancellationToken::new();
|
||||||
let builder = LspService::build(|client| {
|
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`
|
// 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.
|
// 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();
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,10 @@ impl ReplLanguageServer {
|
||||||
super::logging::set_lsp_log_level(log::Level::Debug);
|
super::logging::set_lsp_log_level(log::Level::Debug);
|
||||||
super::logging::set_lsp_warn_level(log::Level::Debug);
|
super::logging::set_lsp_warn_level(log::Level::Debug);
|
||||||
|
|
||||||
let language_server =
|
let language_server = super::language_server::LanguageServer::new(
|
||||||
super::language_server::LanguageServer::new(Client::new_for_repl());
|
Client::new_for_repl(),
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
|
|
||||||
let cwd_uri = get_cwd_uri()?;
|
let cwd_uri = get_cwd_uri()?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue