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 server = self.server.clone();
|
||||||
let name = self.name.clone();
|
let name = self.name.clone();
|
||||||
|
let server_id = self.server_id;
|
||||||
let mut timer = self.executor.timer(SERVER_SHUTDOWN_TIMEOUT).fuse();
|
let mut timer = self.executor.timer(SERVER_SHUTDOWN_TIMEOUT).fuse();
|
||||||
Some(
|
Some(async move {
|
||||||
async move {
|
log::debug!("language server shutdown started");
|
||||||
log::debug!("language server shutdown started");
|
|
||||||
|
|
||||||
select! {
|
select! {
|
||||||
request_result = shutdown_request.fuse() => {
|
request_result = shutdown_request.fuse() => {
|
||||||
match request_result {
|
match request_result {
|
||||||
ConnectionResult::Timeout => {
|
ConnectionResult::Timeout => {
|
||||||
log::warn!("timeout waiting for language server {name} to shutdown");
|
log::warn!("timeout waiting for language server {name} (id {server_id}) to shutdown");
|
||||||
},
|
},
|
||||||
ConnectionResult::ConnectionReset => {},
|
ConnectionResult::ConnectionReset => {
|
||||||
ConnectionResult::Result(r) => r?,
|
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();
|
_ = timer => {
|
||||||
Self::notify_internal::<notification::Exit>(&outbound_tx, &()).ok();
|
log::info!("timeout waiting for language server {name} (id {server_id}) to shutdown");
|
||||||
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(())
|
|
||||||
}
|
}
|
||||||
.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 {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,10 @@ async function handleMessage(message, prettier) {
|
||||||
throw new Error(`Message method is undefined: ${JSON.stringify(message)}`);
|
throw new Error(`Message method is undefined: ${JSON.stringify(message)}`);
|
||||||
} else if (method == "initialized") {
|
} else if (method == "initialized") {
|
||||||
return;
|
return;
|
||||||
|
} else if (method === "shutdown") {
|
||||||
|
sendResponse({ result: {} });
|
||||||
|
} else if (method == "exit") {
|
||||||
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id === undefined) {
|
if (id === undefined) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue