Skip to main content

sokuto_server/handlers/
ops.rs

1//! # 運用監視エンドポイントハンドラモジュール
2//!
3//! Liveness Probe (`GET /health`), Readiness Probe (`GET /ready`),
4//! および Prometheus メトリクスエクスポート (`GET /metrics`) を提供する。
5
6use std::sync::Arc;
7
8use axum::Extension;
9use axum::extract::State;
10use axum::http::StatusCode;
11use axum::response::{IntoResponse, Response};
12use metrics_exporter_prometheus::PrometheusHandle;
13use serde::Serialize;
14use utoipa::ToSchema;
15
16use crate::state::AppState;
17
18/// ヘルスチェック・準備状態のステータスレスポンス。
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, ToSchema)]
20pub struct HealthStatusResponse {
21    /// 稼働ステータス文字列(`ok`, `ready`, `not_ready`)。
22    pub status: String,
23}
24
25/// Liveness Probe エンドポイント。
26///
27/// サーバープロセスが生存し、HTTP イベントループが正常に応答可能かを即座に判定する。
28#[utoipa::path(
29    get,
30    path = "/health",
31    tag = "Operations",
32    responses(
33        (status = 200, description = "プロセス正常稼働中", body = HealthStatusResponse)
34    )
35)]
36pub async fn health_handler() -> impl IntoResponse {
37    axum::Json(HealthStatusResponse {
38        status: "ok".to_string(),
39    })
40}
41
42/// Readiness Probe エンドポイント。
43///
44/// モデルおよびトークナイザーがロードされ、推論要求を安全に処理可能な状態にあるかを検証する。
45#[utoipa::path(
46    get,
47    path = "/ready",
48    tag = "Operations",
49    responses(
50        (status = 200, description = "推論準備完了", body = HealthStatusResponse),
51        (status = 503, description = "推論エンジン未準備", body = HealthStatusResponse)
52    )
53)]
54pub async fn ready_handler(State(state): State<Arc<AppState>>) -> Response {
55    if state.is_ready() {
56        (
57            StatusCode::OK,
58            axum::Json(HealthStatusResponse {
59                status: "ready".to_string(),
60            }),
61        )
62            .into_response()
63    } else {
64        (
65            StatusCode::SERVICE_UNAVAILABLE,
66            axum::Json(HealthStatusResponse {
67                status: "not_ready".to_string(),
68            }),
69        )
70            .into_response()
71    }
72}
73
74/// Prometheus メトリクスエンドポイント。
75///
76/// 蓄積されたパフォーマンス指標およびリクエスト統計を Prometheus テキスト形式で返却する。
77#[utoipa::path(
78    get,
79    path = "/metrics",
80    tag = "Operations",
81    responses(
82        (status = 200, description = "Prometheus メトリクス出力", content_type = "text/plain; version=0.0.4")
83    )
84)]
85pub async fn metrics_handler(
86    Extension(prometheus_handle): Extension<Option<PrometheusHandle>>,
87) -> impl IntoResponse {
88    match prometheus_handle {
89        Some(handle) => (
90            StatusCode::OK,
91            [("content-type", "text/plain; version=0.0.4; charset=utf-8")],
92            handle.render(),
93        )
94            .into_response(),
95        None => (
96            StatusCode::SERVICE_UNAVAILABLE,
97            "Prometheus メトリクスレコーダーが有効化されていません。",
98        )
99            .into_response(),
100    }
101}