package jobs import ( "log/slog" "sync" "time" "warpbox.dev/backend/libs/config" "warpbox.dev/backend/libs/services" ) type job struct { name string enabled bool interval time.Duration run func() } func StartAll(cfg config.Config, logger *slog.Logger, uploadService *services.UploadService, banService *services.BanService) func() { if !cfg.JobsEnabled { logger.Info("background jobs disabled", "source", "jobs", "severity", "dev") return func() {} } stops := []func(){ start(newCleanupJob(cfg, logger, uploadService, banService), logger), start(newThumbnailsJob(cfg, logger, uploadService), logger), } var once sync.Once return func() { once.Do(func() { for _, stop := range stops { stop() } }) } } func start(j job, logger *slog.Logger) func() { if !j.enabled { logger.Info("background job disabled", "source", "jobs", "severity", "dev", "job", j.name) return func() {} } if j.interval <= 0 { logger.Info("background job disabled by interval", "source", "jobs", "severity", "dev", "job", j.name, "interval", j.interval.String()) return func() {} } stop := make(chan struct{}) done := make(chan struct{}) go func() { defer close(done) j.run() ticker := time.NewTicker(j.interval) defer ticker.Stop() for { select { case <-ticker.C: j.run() case <-stop: return } } }() var once sync.Once return func() { once.Do(func() { close(stop) <-done }) } }