use std::time::Duration;
use crate::cli::{is_running, read_pid_file, BIND_ADDR};
const RESTART_TIMEOUT: Duration = Duration::from_secs(5);
const POLL_INTERVAL: Duration = Duration::from_millis(100);
const RESTART_TIMEOUT_MS_ENV: &str = "MOADIM_RESTART_TIMEOUT_MS";
const POLL_INTERVAL_MS_ENV: &str = "MOADIM_RESTART_POLL_MS";
fn restart_timeout() -> Duration {
parse_millis_env(RESTART_TIMEOUT_MS_ENV).unwrap_or(RESTART_TIMEOUT)
}
fn poll_interval() -> Duration {
parse_millis_env(POLL_INTERVAL_MS_ENV).unwrap_or(POLL_INTERVAL)
}
fn parse_millis_env(name: &str) -> Option<Duration> {
std::env::var(name)
.ok()?
.parse::<u64>()
.ok()
.map(Duration::from_millis)
}
pub fn stop_running_and_wait() -> anyhow::Result<()> {
let _ = crate::cli::http_request("POST", "/api/v1/shutdown");
if wait_until_stopped() {
return Ok(());
}
if let Some(pid) = read_pid_file() {
kill_pid(pid);
}
if wait_until_stopped() {
Ok(())
} else {
anyhow::bail!("could not stop the running moadim instance at http://{BIND_ADDR}")
}
}
fn wait_until_stopped() -> bool {
let deadline = std::time::Instant::now() + restart_timeout();
while std::time::Instant::now() < deadline {
if !is_running() {
return true;
}
std::thread::sleep(poll_interval());
}
!is_running()
}
#[cfg(unix)]
fn kill_pid(pid: u32) {
let _ = std::process::Command::new("kill")
.args(["-9", &pid.to_string()])
.output();
}
#[cfg(not(unix))]
fn kill_pid(pid: u32) {
let _ = std::process::Command::new("taskkill")
.args(["/F", "/PID", &pid.to_string()])
.output();
}
#[cfg(test)]
#[path = "restart_tests.rs"]
mod restart_tests;