1#![cfg(feature = "server")]
12
13use axum::http::StatusCode;
14use axum::Json;
15use serde_json::{json, Value};
16use std::time::Duration;
17
18const PROBE_TIMEOUT: Duration = Duration::from_secs(2);
23
24pub async fn healthz() -> Json<Value> {
29 Json(json!({ "status": "ok" }))
30}
31
32pub async fn readyz() -> (StatusCode, Json<Value>) {
46 use crate::db::pool::DB_POOL;
47
48 let s = DB_POOL.status();
50 let pool_info = json!({
51 "size": s.size,
52 "available": s.available,
53 "max_size": s.max_size,
54 "waiting": s.waiting,
55 });
56
57 match tokio::time::timeout(PROBE_TIMEOUT, DB_POOL.get()).await {
59 Ok(Ok(conn)) => match conn.simple_query("SELECT 1").await {
60 Ok(_) => (
61 StatusCode::OK,
62 Json(json!({ "status": "ready", "db": "ok", "pool": pool_info })),
63 ),
64 Err(e) => (
65 StatusCode::SERVICE_UNAVAILABLE,
66 Json(json!({
67 "status": "unready",
68 "db": "error",
69 "error": e.to_string(),
70 "pool": pool_info
71 })),
72 ),
73 },
74 Ok(Err(e)) => (
75 StatusCode::SERVICE_UNAVAILABLE,
76 Json(json!({
77 "status": "unready",
78 "db": "down",
79 "error": e.to_string(),
80 "pool": pool_info
81 })),
82 ),
83 Err(_) => (
84 StatusCode::SERVICE_UNAVAILABLE,
85 Json(json!({
86 "status": "unready",
87 "db": "timeout",
88 "pool": pool_info
89 })),
90 ),
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn healthz_returns_ok_status() {
100 let expected = json!({ "status": "ok" });
103 assert_eq!(expected["status"], "ok");
104 }
105
106 #[test]
107 fn readyz_pool_info_has_all_fields() {
108 let size = 5usize;
112 let available = 3usize;
113 let max_size = 20usize;
114 let waiting = 0usize;
115 let pool_info = json!({
116 "size": size,
117 "available": available,
118 "max_size": max_size,
119 "waiting": waiting,
120 });
121 assert_eq!(pool_info["max_size"], 20);
122 assert_eq!(pool_info["size"], 5);
123 assert_eq!(pool_info["available"], 3);
124 assert_eq!(pool_info["waiting"], 0);
125 }
126
127 #[test]
128 fn probe_timeout_is_two_seconds() {
129 assert_eq!(PROBE_TIMEOUT, Duration::from_secs(2));
130 }
131}