use crate::proxy_lock;
pub enum StopResult {
Stopped { name: String, pid: u32 },
StaleCleaned { name: String },
}
pub fn start_proxy(name: &str) -> Result<(), String> {
proxy_lock::read_snapshot(name)
.map_err(|e| format!("no config snapshot for proxy \"{name}\": {e}"))?;
let config_path = proxy_lock::config_snapshot_path(name).display().to_string();
let exe = std::env::current_exe().map_err(|e| format!("cannot find mcpr binary: {e}"))?;
let status = std::process::Command::new(exe)
.args(["proxy", "run", "--config", &config_path, "--replace"])
.status()
.map_err(|e| format!("failed to spawn proxy \"{name}\": {e}"))?;
if !status.success() {
return Err(format!("proxy \"{name}\" failed to start"));
}
Ok(())
}
pub fn stop_proxy(name: &str) -> Result<StopResult, String> {
match proxy_lock::check_lock(name) {
proxy_lock::LockStatus::Held(info) => {
let pid = info.pid;
proxy_lock::stop_proxy(name);
Ok(StopResult::Stopped {
name: name.to_string(),
pid,
})
}
proxy_lock::LockStatus::Stale(_) => {
proxy_lock::remove_lock(name);
Ok(StopResult::StaleCleaned {
name: name.to_string(),
})
}
proxy_lock::LockStatus::Free => Err(format!("proxy \"{}\" is not running.", name)),
}
}
pub fn stop_all_proxies() -> Vec<String> {
proxy_lock::stop_all_proxies()
}
pub fn restart_proxy(name: &str) -> Result<(), String> {
proxy_lock::stop_proxy(name);
start_proxy(name)
}
pub fn restart_all_proxies() -> Result<usize, String> {
let proxies = proxy_lock::list_proxies();
let mut restarted = 0;
for (name, status) in &proxies {
match status {
proxy_lock::LockStatus::Held(_) | proxy_lock::LockStatus::Stale(_) => {
restart_proxy(name)?;
restarted += 1;
}
proxy_lock::LockStatus::Free => {}
}
}
Ok(restarted)
}
pub fn list_proxies() -> Vec<(String, proxy_lock::LockStatus)> {
proxy_lock::list_proxies()
}