feat: Health command — version, pid, started_at (proto + daemon)
This commit is contained in:
@@ -62,9 +62,11 @@ pub async fn serve(socket: &Path, store: Arc<dyn StateStore>, event_store: Arc<d
|
||||
let initial = store.load().unwrap_or_default();
|
||||
let event_persister = event_store::spawn(event_store.clone(), Duration::from_millis(500));
|
||||
let event_initial = event_store.load().unwrap_or_default();
|
||||
let started_at_ms = now_millis();
|
||||
let shutdown = tokio::spawn(router(
|
||||
router_rx, router_tx.clone(), exit_tx, state_tx,
|
||||
persister, initial, event_persister, event_initial,
|
||||
started_at_ms,
|
||||
));
|
||||
|
||||
let mut next_client: ClientId = 0;
|
||||
@@ -125,6 +127,7 @@ async fn router(
|
||||
initial: crate::state_store::PersistState,
|
||||
event_persister: EventPersister,
|
||||
event_initial: crate::event_log::EventLogState,
|
||||
started_at_ms: u64,
|
||||
) {
|
||||
let mut reg = Registry::new();
|
||||
reg.restore(initial);
|
||||
@@ -174,7 +177,7 @@ async fn router(
|
||||
ServerMsg::Request { id, cmd, client, out } => {
|
||||
handle_request(id, cmd, client, out, &mut reg, &mut subs, &clients,
|
||||
&router_tx, &exit_tx, &state_tx, &persister,
|
||||
&mut event_log, &event_persister).await;
|
||||
&mut event_log, &event_persister, started_at_ms).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,6 +275,7 @@ async fn handle_request(
|
||||
persister: &Persister,
|
||||
event_log: &mut EventLog,
|
||||
event_persister: &EventPersister,
|
||||
started_at_ms: u64,
|
||||
) {
|
||||
use spacesh_proto::message::SplitDir;
|
||||
use spacesh_proto::layout::{LayoutNode, Orient};
|
||||
@@ -590,6 +594,14 @@ async fn handle_request(
|
||||
}
|
||||
}
|
||||
|
||||
Cmd::Health => {
|
||||
let _ = out.send(ok(id, serde_json::json!({
|
||||
"version": env!("CARGO_PKG_VERSION"),
|
||||
"pid": std::process::id(),
|
||||
"started_at_ms": started_at_ms,
|
||||
}))).await;
|
||||
}
|
||||
|
||||
Cmd::Status => {
|
||||
let (groups, workspaces) = reg.status();
|
||||
let _ = out.send(ok(id, serde_json::json!({ "groups": groups, "workspaces": workspaces }))).await;
|
||||
@@ -1300,4 +1312,27 @@ mod tests {
|
||||
let log = req(&mut s, 6, Cmd::EventLog { limit: None }).await;
|
||||
assert_eq!(res_data(&log)["unread"].as_u64().unwrap(), 0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn health_reports_version_pid_started() {
|
||||
let _serial = crate::test_support::serial();
|
||||
let dir = tempdir_path();
|
||||
let sock = dir.join("sock");
|
||||
let store: std::sync::Arc<dyn crate::state_store::StateStore> =
|
||||
std::sync::Arc::new(crate::state_store::JsonStateStore::new(dir.join("state.json")));
|
||||
let event_store = make_event_store(&dir);
|
||||
let sock_for_task = sock.clone();
|
||||
let store2 = store.clone();
|
||||
tokio::spawn(async move { let _ = serve(&sock_for_task, store2, event_store).await; });
|
||||
wait_for_socket(&sock).await;
|
||||
let mut s = UnixStream::connect(&sock).await.unwrap();
|
||||
|
||||
let now = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() as u64;
|
||||
let r = req(&mut s, 1, Cmd::Health).await;
|
||||
let d = res_data(&r);
|
||||
assert!(!d["version"].as_str().unwrap().is_empty());
|
||||
assert!(d["pid"].as_u64().unwrap() > 0);
|
||||
let started = d["started_at_ms"].as_u64().unwrap();
|
||||
assert!(started > 0 && started >= now.saturating_sub(5000) && started <= now + 1000, "started_at_ms plausible: {started} vs now {now}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user