You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/health returns a static {"status": "ok"} regardless of whether the model is loaded or dependencies (spam-words SQLite, rate-limit store) are reachable, so an orchestrator can route traffic to an instance that will 5xx every prediction. There is also no graceful shutdown: a SIGTERM drops in-flight requests immediately.
Proposed solution
Split health into liveness and readiness, make readiness reflect real dependencies, and drain in-flight requests on shutdown.
Track in-flight requests in before_request/after_request.
A SIGTERM handler that flips readiness to draining (so /health/ready returns 503 and load balancers stop routing), waits for in-flight requests to finish up to a bounded timeout, then exits.
README + OpenAPI paths; regression coverage for ready/live states and the drain flag.
Acceptance criteria
/health/ready is 503 before the model loads / when a dependency is down, and 200 otherwise; /health/live is independent of dependencies.
/health still responds as today (no breaking change).
After SIGTERM, readiness reports draining and in-flight requests complete before exit (covered by a test with a fake slow request).
Problem
/healthreturns a static{"status": "ok"}regardless of whether the model is loaded or dependencies (spam-words SQLite, rate-limit store) are reachable, so an orchestrator can route traffic to an instance that will 5xx every prediction. There is also no graceful shutdown: a SIGTERM drops in-flight requests immediately.Proposed solution
Split health into liveness and readiness, make readiness reflect real dependencies, and drain in-flight requests on shutdown.
Scope
GET /health/live— process is up (always 200).GET /health/ready— 200 only when the serving state is populated and the spam-words DB + rate-limit store respond; otherwise 503 with the standard error envelope ([Feature]: Standardize Flask ML API errors behind a machine-readable error envelope (backward compatible) #986).GET /healthas a backward-compatible alias.before_request/after_request.draining(so/health/readyreturns 503 and load balancers stop routing), waits for in-flight requests to finish up to a bounded timeout, then exits.Acceptance criteria
/health/readyis 503 before the model loads / when a dependency is down, and 200 otherwise;/health/liveis independent of dependencies./healthstill responds as today (no breaking change).Out of scope
Kubernetes manifests/probe configuration; multi-process (gunicorn) worker coordination.