package api import ( "context" "encoding/hex" "net/http" "time" "github.com/ponzischeme89/memby/server/internal/buildinfo" ) func hexHash(hash []byte) string { return hex.EncodeToString(hash) } // handleHealth is liveness: the process is up. It touches no dependency, so an // orchestrator does not restart the container just because Emby is down. // It also names the build, so "which server is answering" can be settled with one curl // against a machine whose logs are not to hand. func (s *Server) handleHealth(w http.ResponseWriter, _ *http.Request) { writeJSON(w, http.StatusOK, map[string]any{ "status": "ok", "version": buildinfo.Version(), "protocol": ProtocolVersion, }) } // handleReady is readiness: everything this service needs is reachable. func (s *Server) handleReady(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second) defer cancel() checks := map[string]string{} status := http.StatusOK if err := s.store.Ping(ctx); err != nil { checks["postgres"] = err.Error() status = http.StatusServiceUnavailable } else { checks["postgres"] = "ok" } if err := s.cache.Ping(ctx); err != nil { checks["redis"] = err.Error() status = http.StatusServiceUnavailable } else { checks["redis"] = "ok" } // Emby being unreachable is reported but does not fail readiness: cached responses // are still worth serving, and flapping the container would not bring Emby back. if err := s.emby.Ping(ctx); err != nil { checks["emby"] = err.Error() } else { checks["emby"] = "ok" } writeJSON(w, status, checks) }