veza/veza-backend-api/internal/workers/playback_retention_worker.go
2025-12-03 20:29:37 +01:00

127 lines
3.3 KiB
Go

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
}