1use crate::operator::Operator;
7use axum::Router;
8use axum::extract::State;
9use axum::http::StatusCode;
10use axum::routing::get;
11use std::sync::Arc;
12use std::time::Duration;
13
14pub const READY_TIMEOUT: Duration = Duration::from_secs(2);
16
17pub fn router(operator: Arc<Operator>) -> Router {
18 Router::new()
19 .route("/healthz", get(|| async { "ok" }))
20 .route("/readyz", get(ready))
21 .with_state(operator)
22}
23
24async fn ready(State(operator): State<Arc<Operator>>) -> (StatusCode, &'static str) {
29 let ping = tokio::task::spawn_blocking(move || operator.ping());
30 let why = match tokio::time::timeout(READY_TIMEOUT, ping).await {
31 Ok(Ok(Ok(()))) => return (StatusCode::OK, "ready"),
32 Ok(Ok(Err(err))) => format!("{err:#}"),
33 Ok(Err(err)) => err.to_string(),
34 Err(_) => format!("no answer within {READY_TIMEOUT:?}"),
35 };
36 tracing::warn!(error = %why, "readyz: the database does not answer");
37 (StatusCode::SERVICE_UNAVAILABLE, "not ready")
38}