-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
signal handling / graceful shutdown #124
Comments
One use case in particular to highlight would be testing. I just ran into this and worked around the lack of a The code isn't the greatest but if anyone runs into this: /// Setup API server for use in testing
pub fn setup_api_server_process() -> Result<APIServerTestInfo, Error> {
// Generate configuration for the server
let cfg = AppConfig::new_randomized()?;
let cfg_toml_contents = toml::to_string(&cfg).expect("failed to config to TOML");
// Write config to temp file
let dir = tempdir().unwrap();
let cfg_path = String::from(dir.path().join("cfg.toml").to_str().unwrap());
let mut file: File = File::create(&cfg_path).unwrap();
write!(file, "{}", cfg_toml_contents).expect("Failed to write temporary file");
// Spawn a child process (that never returns) for the API server
let child = Command::new("cargo")
.arg("run")
.arg("--")
.arg("-c")
.arg(cfg_path)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("failed to spawn child thread for test API server");
// Wait for the child process something
// FUTURE: this is fragile, would be better to wait for some sort of "server running" message on stdout
thread::sleep(time::Duration::from_millis(STARTUP_WAIT));
Ok((cfg, child))
} I found a way to make the child process a tiny bit less fragile by waiting on output of a very specific message on // It is surprisingly hard to redirect output from a child process:
// https://stackoverflow.com/questions/42726095/how-to-implement-redirection-of-stdout-of-a-child-process-to-a-file
// https://stackoverflow.com/questions/43949612/redirect-output-of-child-process-spawned-from-rust
let output_path = String::from(dir.path().join("output.log").to_str().unwrap());
let output = File::create(output_path.clone()).unwrap().into_raw_fd();
let raw_output_fd = unsafe {Stdio::from_raw_fd(output)};
// Spawn a child process (that never returns) for the API server
let child = Command::new("cargo")
.arg("run")
.arg("--")
.arg("-c")
.arg(cfg_path)
.stdout(raw_output_fd)
.spawn()
.expect("failed to spawn child thread for test API server");
// Read from the output file to which child process stdout is going, as the child process writes it
let mut output_file = File::open(output_path).unwrap();
let mut log_contents = String::new();
// Wait until the server says it's ready
loop {
output_file.read_to_string(&mut log_contents)?;
if log_contents.contains(SERVER_STARTED_MESSAGE) {
thread::sleep(time::Duration::from_millis(STARTUP_EXTRA_WAIT));
break;
}
} Still not particularly proud of it, but it does work... |
It'd be nice to have a simple way of handling
SIGINT
/SIGTERM
for gracefully shutting down stuffThe text was updated successfully, but these errors were encountered: