Shutdown language servers better (#35038)
Follow-up of https://github.com/zed-industries/zed/pull/33417 * adjust prettier mock LSP to handle `shutdown` and `exit` messages * removed another `?.log_err()` backtrace from logs and improved the logging info * always handle the last parts of the shutdown logic even if the shutdown response had failed Release Notes: - N/A
This commit is contained in:
parent
2a9355a3d2
commit
2658b2801e
2 changed files with 33 additions and 27 deletions
|
@ -877,39 +877,41 @@ impl LanguageServer {
|
|||
|
||||
let server = self.server.clone();
|
||||
let name = self.name.clone();
|
||||
let server_id = self.server_id;
|
||||
let mut timer = self.executor.timer(SERVER_SHUTDOWN_TIMEOUT).fuse();
|
||||
Some(
|
||||
async move {
|
||||
log::debug!("language server shutdown started");
|
||||
Some(async move {
|
||||
log::debug!("language server shutdown started");
|
||||
|
||||
select! {
|
||||
request_result = shutdown_request.fuse() => {
|
||||
match request_result {
|
||||
ConnectionResult::Timeout => {
|
||||
log::warn!("timeout waiting for language server {name} to shutdown");
|
||||
},
|
||||
ConnectionResult::ConnectionReset => {},
|
||||
ConnectionResult::Result(r) => r?,
|
||||
}
|
||||
select! {
|
||||
request_result = shutdown_request.fuse() => {
|
||||
match request_result {
|
||||
ConnectionResult::Timeout => {
|
||||
log::warn!("timeout waiting for language server {name} (id {server_id}) to shutdown");
|
||||
},
|
||||
ConnectionResult::ConnectionReset => {
|
||||
log::warn!("language server {name} (id {server_id}) closed the shutdown request connection");
|
||||
},
|
||||
ConnectionResult::Result(Err(e)) => {
|
||||
log::error!("Shutdown request failure, server {name} (id {server_id}): {e:#}");
|
||||
},
|
||||
ConnectionResult::Result(Ok(())) => {}
|
||||
}
|
||||
|
||||
_ = timer => {
|
||||
log::info!("timeout waiting for language server {name} to shutdown");
|
||||
},
|
||||
}
|
||||
|
||||
response_handlers.lock().take();
|
||||
Self::notify_internal::<notification::Exit>(&outbound_tx, &()).ok();
|
||||
outbound_tx.close();
|
||||
output_done.recv().await;
|
||||
server.lock().take().map(|mut child| child.kill());
|
||||
log::debug!("language server shutdown finished");
|
||||
|
||||
drop(tasks);
|
||||
anyhow::Ok(())
|
||||
_ = timer => {
|
||||
log::info!("timeout waiting for language server {name} (id {server_id}) to shutdown");
|
||||
},
|
||||
}
|
||||
.log_err(),
|
||||
)
|
||||
|
||||
response_handlers.lock().take();
|
||||
Self::notify_internal::<notification::Exit>(&outbound_tx, &()).ok();
|
||||
outbound_tx.close();
|
||||
output_done.recv().await;
|
||||
server.lock().take().map(|mut child| child.kill());
|
||||
drop(tasks);
|
||||
log::debug!("language server shutdown finished");
|
||||
Some(())
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -152,6 +152,10 @@ async function handleMessage(message, prettier) {
|
|||
throw new Error(`Message method is undefined: ${JSON.stringify(message)}`);
|
||||
} else if (method == "initialized") {
|
||||
return;
|
||||
} else if (method === "shutdown") {
|
||||
sendResponse({ result: {} });
|
||||
} else if (method == "exit") {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (id === undefined) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue