package worker import ( "context" "errors" "log/slog" "time" "galaxy/mail/internal/adapters/redisstate" ) const cleanupInterval = time.Hour // CleanupWorker stores the idle index cleanup worker used by the Stage 6 // runtime skeleton. type CleanupWorker struct { cleaner *redisstate.IndexCleaner logger *slog.Logger } // NewCleanupWorker constructs the idle Stage 6 cleanup worker. func NewCleanupWorker(cleaner *redisstate.IndexCleaner, logger *slog.Logger) (*CleanupWorker, error) { if cleaner == nil { return nil, errors.New("new cleanup worker: nil index cleaner") } if logger == nil { logger = slog.Default() } return &CleanupWorker{ cleaner: cleaner, logger: logger.With("component", "cleanup_worker"), }, nil } // Run starts the idle cleanup worker and blocks until ctx is canceled. func (worker *CleanupWorker) Run(ctx context.Context) error { if ctx == nil { return errors.New("run cleanup worker: nil context") } if err := ctx.Err(); err != nil { return err } if worker == nil || worker.cleaner == nil { return errors.New("run cleanup worker: nil cleanup worker") } worker.logger.Info("cleanup worker started", "interval", cleanupInterval.String()) ticker := time.NewTicker(cleanupInterval) defer ticker.Stop() for { select { case <-ctx.Done(): worker.logger.Info("cleanup worker stopped") return ctx.Err() case <-ticker.C: } } } // Shutdown stops the cleanup worker within ctx. The Stage 6 skeleton has no // additional resources to release. func (worker *CleanupWorker) Shutdown(ctx context.Context) error { if ctx == nil { return errors.New("shutdown cleanup worker: nil context") } if worker == nil { return nil } return nil }