//! `GET /health` and `GET /ready`: unauthenticated, for supervisors and load balancers. //! They say whether the node is up and whether it serves the store, and `/health` on a //! node whether its clock is off, nothing more. use std::time::Duration; use axum::{extract::State, http::StatusCode}; use crate::state::AppState; /// The HTTP API is up (a relay's). pub(crate) async fn health() -> &'static str { "ok\n" } /// The HTTP API is up (a node's); a second line while its clock is off from its peers' /// (`swarm::skew`), which doesn't make it less up. pub(crate) async fn node_health(State(state): State) -> String { let skew = crate::swarm::skew::measure(&state).await; match skew.offset_ms { Some(offset) if skew.off => format!( "ok\nclock off: {} {} most of its peers'\n", crate::units::format_duration(Duration::from_millis(offset.unsigned_abs())), if offset < 0 { "behind" } else { "ahead of" } ), _ => "ok\n".to_owned(), } } /// The node serves reads and writes: ready, not joining or rejoining. pub(crate) async fn ready(State(state): State) -> (StatusCode, &'static str) { if state.is_ready().await { (StatusCode::OK, "ready\n") } else { (StatusCode::SERVICE_UNAVAILABLE, "not ready\n") } }