| 1 | package daemon |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "net/http" |
| 6 | "time" |
| 7 | ) |
| 8 | |
| 9 | const healthProbeTimeout = 500 * time.Millisecond |
| 10 | |
| 11 | func (a *App) healthHTTP(w http.ResponseWriter, r *http.Request) { |
| 12 | if r.URL.Path == "/healthz" { |
| 13 | if a.isClosed() { |
| 14 | writeJSON(w, http.StatusServiceUnavailable, map[string]string{"status" : "shutting_down" }) |
| 15 | return |
| 16 | } |
| 17 | writeJSON(w, http.StatusOK, map[string]string{"status" : "alive" }) |
| 18 | return |
| 19 | } |
| 20 | if r.URL.Path == "/readyz" { |
| 21 | if err := a.ready(r.Context()); err != nil { |
| 22 | writeJSON(w, http.StatusServiceUnavailable, map[string]string{"status" : "unready" }) |
| 23 | return |
| 24 | } |
| 25 | writeJSON(w, http.StatusOK, map[string]string{"status" : "ready" }) |
| 26 | return |
| 27 | } |
| 28 | http.NotFound(w, r) |
| 29 | } |
| 30 | |
| 31 | func (a *App) ready(parent context.Context) error { |
| 32 | if a.isClosed() { |
| 33 | return ErrTenantClosing |
| 34 | } |
| 35 | a.lifecycle.mu.Lock() |
| 36 | started := a.lifecycle.started |
| 37 | a.lifecycle.mu.Unlock() |
| 38 | if !started { |
| 39 | return ErrMaintenance |
| 40 | } |
| 41 | ctx, cancel := context.WithTimeout(parent, healthProbeTimeout) |
| 42 | defer cancel() |
| 43 | _, err := a.catalog.List(ctx) |
| 44 | return err |
| 45 | } |
| 46 | |
| 47 | func (a *App) isClosed() bool { |
| 48 | a.mu.Lock() |
| 49 | defer a.mu.Unlock() |
| 50 | return a.closed |
| 51 | } |
| 52 | |
| 53 | func (t *Tenant) healthHTTP(w http.ResponseWriter, r *http.Request) { |
| 54 | ctx, done, err := t.beginOperation(r.Context()) |
| 55 | if err != nil { |
| 56 | writeJSON(w, http.StatusServiceUnavailable, map[string]string{"status" : "unavailable" }) |
| 57 | return |
| 58 | } |
| 59 | defer done() |
| 60 | probeCtx, cancel := context.WithTimeout(ctx, healthProbeTimeout) |
| 61 | defer cancel() |
| 62 | if err := t.store.DB().PingContext(probeCtx); err != nil { |
| 63 | writeJSON(w, http.StatusServiceUnavailable, map[string]string{"status" : "unavailable" }) |
| 64 | return |
| 65 | } |
| 66 | writeJSON(w, http.StatusOK, map[string]string{"status" : "ready" }) |
| 67 | } |