fix(apps): add periodic liveness re-check for app backends - #6079
fix(apps): add periodic liveness re-check for app backends#6079aniruddhaadak80 wants to merge 1 commit into
Conversation
After the initial startup health check passes, _health_check_loop now continues periodic liveness re-checks at _LIVENESS_RECHECK_INTERVAL (30s). If the backend process exits or the health endpoint fails _LIVENESS_MAX_CONSECUTIVE_FAILURES (3) consecutive times, the backend is marked unhealthy (healthy=False) so the reverse proxy stops routing to it, and MCP entries are scrubbed. This fixes kirodotdev#5726 — backends that die after startup were never detected, causing permanent 502/504 proxy errors and stale dashboard status.
|
👋 Hi! This PR is currently in draft status. Workflow runs won't be auto-approved until it's marked as ready for review. When you're ready, click "Ready for review" and the workflows will be approved on the next cycle automatically. |
1 similar comment
|
👋 Hi! This PR is currently in draft status. Workflow runs won't be auto-approved until it's marked as ready for review. When you're ready, click "Ready for review" and the workflows will be approved on the next cycle automatically. |
|
👋 Hi! This PR is currently in draft status. Workflow runs won't be auto-approved until it's marked as ready for review. When you're ready, click "Ready for review" and the workflows will be approved on the next cycle automatically. |
1 similar comment
|
👋 Hi! This PR is currently in draft status. Workflow runs won't be auto-approved until it's marked as ready for review. When you're ready, click "Ready for review" and the workflows will be approved on the next cycle automatically. |
|
Closing this draft as superseded by merged #5929. Main already owns the backend liveness supervisor, failure demotion/recovery, generation fencing, and MCP reconciliation; the remaining safe-probe residual belongs in the narrower #5727 follow-up rather than this duplicate draft. No branch is deleted. |
|
Full-diff overlap audit (current head Coordination: #6092 literally carries this exact #6079 commit and should drop it while retaining only its still-unique |
What Problem This Solves
App backends are health-checked exactly once at startup. After
_health_check_loopmarks a backend healthy, there is no liveness re-check of any kind. A backend that dies later keeps being treated as healthy: the reverse proxy still routes to its port (producing permanent 502/504 errors) and/api/appsreportsrunning: true, healthy: truefor a dead process.Why This Change Was Made
The startup health-check thread (
_health_check_loop) already runs on its own daemon thread per backend. After the initial startup poll succeeds, the thread now continues periodic liveness re-checks instead of returning permanently.Two demotion signals, both cheap-first:
proc.poll()catches a dead spawned process instantly (free, no HTTP round-trip). An exited process cannot recover, so one observation is enough._LIVENESS_MAX_CONSECUTIVE_FAILURES = 3) avoids false demotion on a single slow response. Demotion is reversible: if the backend recovers, the next successful probe resets the counter.Demotion sets
healthy=False(stopping proxy routing viaget_app_backend_port) and calls_gate_mcp_registration(..., healthy=False)to scrub the MCP entry.User Impact
Evidence
test_app_backend.py::TestHealthGatedMcpRegistration,test_apps_backend_coverage.py::TestHealthCheckLoop)TestLivenessRecheck:test_process_exit_demotes_unhealthy-- killed process triggers immediate demotiontest_consecutive_http_failures_demote_unhealthy-- N consecutive failures triggers demotiontest_liveness_exits_when_process_removed-- clean exit when backend is stoppedFixes #5726