haiku.rag/haiku_rag_slim/haiku/rag/ingester/api/routes/health.py
2026-05-27 10:52:48 +03:00

43 lines
1.9 KiB
Python

from fastapi import APIRouter, Depends
from haiku.rag.ingester.api.schemas import HealthResponse
from haiku.rag.ingester.api.server import APIState, get_state
router = APIRouter()
@router.get("/health", response_model=HealthResponse)
async def health(state: APIState = Depends(get_state)) -> HealthResponse:
"""Liveness signal + queue/worker overview. Unauthenticated so load
balancers and uptime monitors can hit it without a token.
`status="degraded"` when at least one configured worker or poller task
has died (workers_alive < worker_count or pollers_alive < poller_count).
The DB query alone can't catch that — workers might be all dead and the
queue would still report counts cheerfully — so this branch is what
actually distinguishes "alive" from "alive but doing nothing useful".
"""
counts = await state.job_repo.counts_by_status()
worker_count = (
state.config.ingester.workers.worker_count if state.pool is not None else 0
)
workers_alive = state.pool.live_workers if state.pool is not None else 0
poller_count = len(state.pollers.pollers) if state.pollers is not None else 0
pollers_alive = state.pollers.live_pollers if state.pollers is not None else 0
breaker_open = state.pool.breaker_open if state.pool is not None else False
breaker_failures = (
state.pool.breaker_consecutive_failures if state.pool is not None else 0
)
degraded = (
workers_alive < worker_count or pollers_alive < poller_count or breaker_open
)
return HealthResponse(
status="degraded" if degraded else "ok",
queue_counts=counts,
worker_count=worker_count,
poller_count=poller_count,
workers_alive=workers_alive,
pollers_alive=pollers_alive,
worker_breaker_open=breaker_open,
worker_breaker_consecutive_failures=breaker_failures,
)