summaryrefslogtreecommitdiff
path: root/cmd/dashboard
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/dashboard')
-rw-r--r--cmd/dashboard/main.go18
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"))
})