tidaldb/tidal-server/src/health.rs
jx12n b55ad70141 fix: M0-M10 third-pass remediation — durability, replication, and CLI hardening
Resolves the 142 findings from tidal/docs/reviews/CODE_REVIEW_m0-m10.md across
the engine, server, net, and CLI surfaces:

- WAL/session-journal durability, checkpoint format, and crash-recovery hardening
- Replication shipper/receiver, tenant isolation, and migration paths
- Cluster scatter-gather, router, standalone server + health/offload endpoints
- tidalctl refactored into command modules with JSON output and WAL-state tooling
- Cohort, governance, signal-ledger, and vector-registry correctness fixes
- Expanded UAT/integration/durability test coverage across all milestones
2026-06-08 10:28:34 -06:00

48 lines
1.9 KiB
Rust

//! Shared health-probe handlers for the standalone and cluster routers.
//!
//! The standalone router ([`crate::router`]) and the cluster router
//! ([`crate::cluster`]) both expose the same Kubernetes-style probe endpoints
//! `GET /health/startup` and `GET /health/live`. Their handlers and the JSON
//! body they return were previously byte-identical copies in each module; any
//! drift between the two (e.g. a renamed field on one side) would silently
//! change one mode's probe contract. This module is the single source of truth
//! so the two routers cannot diverge, mirroring the [`crate::dto`] anti-drift
//! pattern for the data surface.
use axum::Json;
/// Shared probe body: `{"ok": true, "service": "tidaldb"}`.
///
/// Both `/health/startup` and `/health/live` return this fixed body — they are
/// unconditional 200s (the process is up and there are no migrations to gate
/// readiness on). The richer mode-specific readiness check (`GET /health`)
/// stays in each router because it inspects mode-specific state.
fn probe_body() -> serde_json::Value {
serde_json::json!({ "ok": true, "service": "tidaldb" })
}
/// Startup probe: always 200 (no migrations to check).
pub async fn health_startup() -> Json<serde_json::Value> {
Json(probe_body())
}
/// Liveness probe: always 200 (process is alive).
pub async fn health_live() -> Json<serde_json::Value> {
Json(probe_body())
}
#[cfg(test)]
mod tests {
use super::*;
/// Both probes return the same fixed body, so the standalone and cluster
/// routers cannot advertise a different probe contract.
#[tokio::test]
async fn probes_return_shared_body() {
let expected = serde_json::json!({ "ok": true, "service": "tidaldb" });
assert_eq!(health_startup().await.0, expected);
assert_eq!(health_live().await.0, expected);
assert_eq!(probe_body(), expected);
}
}