package worker import ( "context" "log/slog" "strconv" "time" "git.vakhrushev.me/av/transcriber/internal/contract" "git.vakhrushev.me/av/transcriber/internal/metrics" ) // Worker представляет базовый интерфейс для всех воркеров type Worker interface { Start(ctx context.Context) Name() string } type CallbackWorker struct { name string f func() error logger *slog.Logger } func NewCallbackWorker(name string, f func() error, logger *slog.Logger) *CallbackWorker { if logger == nil { logger = slog.Default() } return &CallbackWorker{ name: name, f: f, logger: logger, } } func (w *CallbackWorker) Name() string { return w.name } func (w *CallbackWorker) Start(ctx context.Context) { w.logger.Info("Worker started", "worker", w.Name()) for { select { case <-ctx.Done(): w.logger.Info("Worker received shutdown signal", "worker", w.Name()) return default: err := w.f() _, isNoop := err.(*contract.NoopJobError) if !isNoop { metrics.WorkerJobCounter.WithLabelValues(w.Name(), strconv.FormatBool(err != nil)).Inc() } if err != nil && !isNoop { w.logger.Error("Worker error", "worker", w.Name(), "error", err) } // Ждем 1 секунду перед следующей итерацией select { case <-ctx.Done(): w.logger.Info("Worker received shutdown signal during sleep", "worker", w.Name()) return case <-time.After(1 * time.Second): // Продолжаем работу } } } }