package workers import ( "context" "time" "veza-backend-api/internal/services" "go.uber.org/zap" "gorm.io/gorm" ) // PlaybackRetentionWorker gère l'exécution périodique de la politique de rétention // T0382: Create Playback Analytics Data Retention Policy type PlaybackRetentionWorker struct { db *gorm.DB retentionService *services.PlaybackRetentionPolicyService logger *zap.Logger interval time.Duration // Intervalle d'exécution policy *services.RetentionPolicy stopChan chan struct{} running bool } // NewPlaybackRetentionWorker crée un nouveau worker de rétention func NewPlaybackRetentionWorker( db *gorm.DB, retentionService *services.PlaybackRetentionPolicyService, logger *zap.Logger, interval time.Duration, ) *PlaybackRetentionWorker { if logger == nil { logger = zap.NewNop() } if interval <= 0 { interval = 24 * time.Hour // Par défaut, exécuter quotidiennement } return &PlaybackRetentionWorker{ db: db, retentionService: retentionService, logger: logger, interval: interval, policy: services.DefaultRetentionPolicy(), stopChan: make(chan struct{}), running: false, } } // SetPolicy définit la politique de rétention à utiliser func (w *PlaybackRetentionWorker) SetPolicy(policy *services.RetentionPolicy) { if policy != nil { w.policy = policy } } // Start démarre le worker de rétention // T0382: Create Playback Analytics Data Retention Policy func (w *PlaybackRetentionWorker) Start(ctx context.Context) { if w.running { w.logger.Warn("Retention worker is already running") return } w.running = true w.logger.Info("Starting playback retention worker", zap.Duration("interval", w.interval), zap.Duration("archive_after", w.policy.ArchiveAfter), zap.Duration("delete_after", w.policy.DeleteAfter)) // Exécuter immédiatement au démarrage go w.runRetentionPolicy(ctx) // Puis exécuter périodiquement ticker := time.NewTicker(w.interval) defer ticker.Stop() for { select { case <-ctx.Done(): w.logger.Info("Stopping playback retention worker") w.running = false return case <-w.stopChan: w.logger.Info("Stopping playback retention worker (stop requested)") w.running = false return case <-ticker.C: go w.runRetentionPolicy(ctx) } } } // Stop arrête le worker de rétention func (w *PlaybackRetentionWorker) Stop() { if !w.running { return } close(w.stopChan) } // runRetentionPolicy exécute la politique de rétention func (w *PlaybackRetentionWorker) runRetentionPolicy(ctx context.Context) { logger := w.logger.With(zap.String("worker", "playback_retention")) logger.Info("Running playback retention policy") // Créer un contexte avec timeout pour éviter les blocages retentionCtx, cancel := context.WithTimeout(ctx, 1*time.Hour) defer cancel() // Appliquer la politique de rétention if err := w.retentionService.ApplyRetentionPolicy(retentionCtx, w.policy); err != nil { logger.Error("Failed to apply retention policy", zap.Error(err)) return } logger.Info("Playback retention policy applied successfully") } // IsRunning retourne si le worker est en cours d'exécution func (w *PlaybackRetentionWorker) IsRunning() bool { return w.running }