diff options
Diffstat (limited to 'cmd/dashboard')
| -rw-r--r-- | cmd/dashboard/main.go | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go index cb2b757..89d12d1 100644 --- a/cmd/dashboard/main.go +++ b/cmd/dashboard/main.go @@ -209,9 +209,25 @@ func main() { // Rate limiter for agent auth (stricter - 10 requests/minute per IP) agentAuthRateLimiter := appmiddleware.NewRateLimiter(10, time.Minute) - // Health check (no auth) + // Health check (no auth). Actually pings the database rather than + // unconditionally returning 200 -- a health check that can't fail isn't + // a health check, it's a liveness stub. That distinction is exactly what + // let the 2026-08-04 incident (DB/session-touching requests wedged for + // three days) go undetected: this endpoint said "ok" the entire time. + // Note the scope: this proves the DB is reachable, not that every request + // path is healthy -- a hung external API call that doesn't touch the DB + // (the actual incident's mechanism) wouldn't be caught by this alone. + // That class of bug is addressed structurally instead, by requiring every + // Google API call to propagate context (see internal/api/context_audit_test.go). r.Get("/health", func(w http.ResponseWriter, r *http.Request) { + ctx, cancel := context.WithTimeout(r.Context(), config.HealthCheckTimeout) + defer cancel() w.Header().Set("Content-Type", "text/plain") + if err := h.PingDB(ctx); err != nil { + w.WriteHeader(http.StatusServiceUnavailable) + _, _ = w.Write([]byte("db unreachable: " + err.Error())) + return + } w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("ok")) }) |
