Use live MQTT readiness for server health checks
This commit is contained in:
@@ -40,6 +40,7 @@ type Snapshot struct {
|
||||
Compatibility []Compatibility `json:"compatibility"`
|
||||
}
|
||||
type Viewer struct {
|
||||
ready func() bool
|
||||
cfg config.Web
|
||||
store *events.Store
|
||||
shutdown time.Duration
|
||||
@@ -60,10 +61,25 @@ func New(cfg config.Web, store *events.Store, shutdown time.Duration) *Viewer {
|
||||
mux.Handle("GET /assets/", http.StripPrefix("/assets/", http.FileServer(http.FS(sub))))
|
||||
mux.HandleFunc("GET /api/snapshot", v.snapshot)
|
||||
mux.HandleFunc("GET /api/events", v.stream)
|
||||
mux.HandleFunc("GET /healthz", v.health)
|
||||
v.handler = v.guard(mux)
|
||||
v.server = &http.Server{Handler: v.handler, ReadHeaderTimeout: 3 * time.Second, IdleTimeout: 20 * time.Second, MaxHeaderBytes: 8 << 10}
|
||||
return v
|
||||
}
|
||||
|
||||
// SetReadiness must be called before Start. Readiness reflects live MQTT state,
|
||||
// independent of connection events rolling out of the bounded viewer history.
|
||||
func (v *Viewer) SetReadiness(ready func() bool) { v.ready = ready }
|
||||
|
||||
func (v *Viewer) health(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
if v.ready == nil || !v.ready() {
|
||||
http.Error(w, "MQTT not ready", http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"status":"ready"}`))
|
||||
}
|
||||
func (v *Viewer) Address() string {
|
||||
if v.listener == nil {
|
||||
return v.cfg.Address
|
||||
|
||||
@@ -162,3 +162,19 @@ func TestReportedScenariosDoNotClaimHardwareCompatibility(t *testing.T) {
|
||||
t.Fatal("scenario aliases retained history")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHealthUsesCurrentMQTTReadiness(t *testing.T) {
|
||||
v := testViewer()
|
||||
ready := false
|
||||
v.SetReadiness(func() bool { return ready })
|
||||
for _, want := range []int{503, 200, 503} {
|
||||
ready = want == 200
|
||||
// No connection event retained: current readiness must still work.
|
||||
r := httptest.NewRequest("GET", "http://127.0.0.1:8080/healthz", nil)
|
||||
w := httptest.NewRecorder()
|
||||
v.Handler().ServeHTTP(w, r)
|
||||
if w.Code != want {
|
||||
t.Fatalf("health status %d, want %d", w.Code, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user