6725: Don't respawn proc macro server on crash r=jonas-schievink a=jonas-schievink

Now the thread managing IPC will exit when the server process crashes instead of respawning it.

Closes https://github.com/rust-analyzer/rust-analyzer/issues/6707

bors r+

Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
bors[bot] 2020-12-04 19:12:49 +00:00 committed by GitHub
commit 571f247fbc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -81,15 +81,16 @@ impl ProcMacroProcessSrv {
{ {
let (result_tx, result_rx) = bounded(0); let (result_tx, result_rx) = bounded(0);
let sender = match self.inner.upgrade() { let sender = match self.inner.upgrade() {
None => { None => return Err(tt::ExpansionError::Unknown("proc macro process is closed".into())),
return Err(tt::ExpansionError::Unknown("Proc macro process is closed.".into()))
}
Some(it) => it, Some(it) => it,
}; };
sender.send(Task { req, result_tx }).unwrap(); sender
.send(Task { req, result_tx })
.map_err(|_| tt::ExpansionError::Unknown("proc macro server crashed".into()))?;
let res = result_rx let res = result_rx
.recv() .recv()
.map_err(|_| tt::ExpansionError::Unknown("Proc macro thread is closed.".into()))?; .map_err(|_| tt::ExpansionError::Unknown("proc macro server crashed".into()))?;
match res { match res {
Some(Response::Error(err)) => { Some(Response::Error(err)) => {
@ -110,21 +111,17 @@ fn client_loop(task_rx: Receiver<Task>, mut process: Process) {
match send_request(&mut stdin, &mut stdout, req) { match send_request(&mut stdin, &mut stdout, req) {
Ok(res) => result_tx.send(res).unwrap(), Ok(res) => result_tx.send(res).unwrap(),
Err(_err) => { Err(_err) => {
log::error!(
"proc macro server crashed, server process state: {:?}",
process.child.try_wait()
);
let res = Response::Error(ResponseError { let res = Response::Error(ResponseError {
code: ErrorCode::ServerErrorEnd, code: ErrorCode::ServerErrorEnd,
message: "Server closed".into(), message: "proc macro server crashed".into(),
}); });
result_tx.send(res.into()).unwrap(); result_tx.send(res.into()).unwrap();
// Restart the process // Exit the thread.
if process.restart().is_err() { break;
break;
}
let stdio = match process.stdio() {
None => break,
Some(it) => it,
};
stdin = stdio.0;
stdout = stdio.1;
} }
} }
} }
@ -136,8 +133,6 @@ struct Task {
} }
struct Process { struct Process {
path: PathBuf,
args: Vec<OsString>,
child: Child, child: Child,
} }
@ -152,15 +147,9 @@ impl Process {
path: PathBuf, path: PathBuf,
args: impl IntoIterator<Item = impl AsRef<OsStr>>, args: impl IntoIterator<Item = impl AsRef<OsStr>>,
) -> io::Result<Process> { ) -> io::Result<Process> {
let args = args.into_iter().map(|s| s.as_ref().into()).collect(); let args: Vec<OsString> = args.into_iter().map(|s| s.as_ref().into()).collect();
let child = mk_child(&path, &args)?; let child = mk_child(&path, &args)?;
Ok(Process { path, args, child }) Ok(Process { child })
}
fn restart(&mut self) -> io::Result<()> {
let _ = self.child.kill();
self.child = mk_child(&self.path, &self.args)?;
Ok(())
} }
fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> { fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> {