package worker import ( "context" "log/slog" "github.com/TopherMayor/unified-media-manager/internal/config" "github.com/TopherMayor/unified-media-manager/internal/service" ) type HealthChecker struct { indexerSvc *service.IndexerService dcSvc *service.DownloadClientService cfg *config.Config } func NewHealthChecker(indexerSvc *service.IndexerService, dcSvc *service.DownloadClientService, cfg *config.Config) *HealthChecker { return &HealthChecker{ indexerSvc: indexerSvc, dcSvc: dcSvc, cfg: cfg, } } func (w *HealthChecker) Name() string { return "health_check" } func (w *HealthChecker) CronExpr() string { return w.cfg.WorkerHealthCheckInterval } func (w *HealthChecker) Run(ctx context.Context) error { healthy := 0 unhealthy := 0 indexers, err := w.indexerSvc.List(ctx) if err != nil { slog.Error("failed to list indexers", "error", err) } else { for _, idx := range indexers { _, testErr := w.indexerSvc.Test(ctx, idx.ID) if testErr != nil { unhealthy++ slog.Warn("indexer health check failed", "id", idx.ID, "name", idx.Name, "error", testErr) } else { healthy++ } } } clients, err := w.dcSvc.List(ctx) if err != nil { slog.Error("failed to list download clients", "error", err) } else { for _, dc := range clients { _, testErr := w.dcSvc.Test(ctx, dc.ID) if testErr != nil { unhealthy++ slog.Warn("download client health check failed", "id", dc.ID, "name", dc.Name, "error", testErr) } else { healthy++ } } } slog.Info("health check completed", "healthy", healthy, "unhealthy", unhealthy) return nil }