use std::time::Duration;
use anyhow::Result;
use broker_client::{probe, send_request};
use config::Config;
use ipc::{BrokerRequest, BrokerResponse};
const STOP_CONFIRM_BOUND: Duration = Duration::from_secs(5);
pub(in crate::commands) async fn run_status(
cfg: &Config,
device: Option<&str>,
label: &str,
) -> Result<String> {
let addr = super::resolve_addr(cfg, device);
let Ok(resp) = send_request(addr, BrokerRequest::Status).await else {
return Ok(format!("{label} for {addr}: not running"));
};
match resp {
BrokerResponse::StatusInfo { state, device: dev, .. } => {
Ok(format!("{label} for {dev}: {state}"))
}
other => Ok(format!("unexpected response: {other:?}")),
}
}
pub(in crate::commands) async fn run_stop(cfg: &Config, device: Option<&str>) -> Result<String> {
let addr = super::resolve_addr(cfg, device);
let Ok(resp) = send_request(addr, BrokerRequest::Shutdown).await else {
return Ok(format!("daemon for {addr}: not running"));
};
match resp {
BrokerResponse::Ok => {
await_unreachable(addr).await;
Ok(format!("daemon for {addr}: stopping"))
}
BrokerResponse::Error(e) => Ok(format!("daemon for {addr}: {e}")),
other => Ok(format!("unexpected response: {other:?}")),
}
}
async fn await_unreachable(addr: &str) {
let Some(deadline) = tokio::time::Instant::now().checked_add(STOP_CONFIRM_BOUND) else {
return;
};
while tokio::time::Instant::now() < deadline {
if !probe(addr).await {
return;
}
tokio::time::sleep(Duration::from_millis(25)).await;
}
}