// Package system — служебные эндпоинты: живость, готовность, сведения о сервере. package system import ( "context" "time" "pipu/api/internal/api/gen" ) // Checker проверяет одну зависимость (БД, Redis, ...). Возвращает ошибку, если она недоступна. type Checker interface { Check(ctx context.Context) error } // CheckerFunc адаптирует функцию к Checker. type CheckerFunc func(ctx context.Context) error // Check реализует Checker. func (f CheckerFunc) Check(ctx context.Context) error { return f(ctx) } // Info — статические сведения о сервере. type Info struct { Version string SupportedLocales []string MinAndroidVersionCode int } // Handler реализует системную часть gen.StrictServerInterface. type Handler struct { info Info checks map[string]Checker checkTimeout time.Duration } // NewHandler создаёт обработчик. checks — именованные проверки для /readyz. func NewHandler(info Info, checks map[string]Checker) *Handler { return &Handler{info: info, checks: checks, checkTimeout: 2 * time.Second} } // GetHealthz сообщает, что процесс жив; зависимости не проверяет. func (h *Handler) GetHealthz(context.Context, gen.GetHealthzRequestObject) (gen.GetHealthzResponseObject, error) { return gen.GetHealthz200JSONResponse{Status: gen.HealthStatusStatusOk}, nil } // GetReadyz проверяет все зависимости; 503, если хотя бы одна недоступна. func (h *Handler) GetReadyz(ctx context.Context, _ gen.GetReadyzRequestObject) (gen.GetReadyzResponseObject, error) { ctx, cancel := context.WithTimeout(ctx, h.checkTimeout) defer cancel() results := make(map[string]string, len(h.checks)) healthy := true for name, c := range h.checks { if err := c.Check(ctx); err != nil { results[name] = err.Error() healthy = false continue } results[name] = "ok" } if !healthy { return gen.GetReadyz503JSONResponse{Status: gen.ReadyStatusStatusDegraded, Checks: results}, nil } return gen.GetReadyz200JSONResponse{Status: gen.ReadyStatusStatusOk, Checks: results}, nil } // GetServerInfo отдаёт сведения о сервере для экрана подключения клиентов. func (h *Handler) GetServerInfo(context.Context, gen.GetServerInfoRequestObject) (gen.GetServerInfoResponseObject, error) { return gen.GetServerInfo200JSONResponse{ Name: "pipu-music", Version: h.info.Version, ApiVersion: "v1", SupportedLocales: h.info.SupportedLocales, MinAndroidVersionCode: h.info.MinAndroidVersionCode, }, nil }