Tide doesn't allow programmatic graceful shutdown or remove unix sockets either. If we add this handler, we can both ensure that we remove the socket and also exit with a successful error code by sending a request to /terminate
.
app.at("/terminate").get(|_| async {let _result =fs::remove_file("/var/tmp/toaster.sock");process::exit(0);#[allow(unreachable_code)]Ok("done")});
example curl command:
curl --unix-socket /var/tmp/toaster.sock http://localhost/terminate
The handler in this case was added to this tide server.
use async_std::task;use futures::try_join;use std::fs;use std::io::{self, Write};use std::process::{self, Command};#[async_std::main]async fn main() -> Result<(), io::Error> {let mut app = tide::new();let sock =format!("http+unix://{}", "/var/tmp/toaster.sock");app.at("/").get(|_| async { Ok("Hello, world!") });let server = app.listen(sock);// node script creationlet child = task::spawn(async {println!("child");let cmd =Command::new("node").arg("index.js").output();io::stdout().write_all(&cmd.unwrap().stdout).unwrap();Ok(())});// results of both futures// result is Result<((),()), Error>let result = try_join!(server, child);match result {Err(e) => Err(e),Ok(_) => Ok(()),}}
We could have also sent a sigterm to ourselves using the nix crate which results in a fatal exit code 130.
use nix::sys::signal::{self, Signal};use nix::unistd::{getpid, Pid};...signal::kill(getpid(), Signal::SIGINT).unwrap();
We could also have panic'ed which would call destructors, but this results in a nonzero exit code.
Rocket supports shutdown but it doesn't support unix sockets.