diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-17 15:25:52 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-17 15:25:52 +0300 |
| commit | 914bd7cd6aa14e839332a98d91c30b19865b0cf2 (patch) | |
| tree | 02b11537237a204048589e14ed24938b805e42f7 /internal/service/scan.go | |
| parent | 3b24f0e1be832584d6550e8cc3e5d24329f66f90 (diff) | |
Restructure repo: move Go server into player-server/
Diffstat (limited to 'internal/service/scan.go')
| -rw-r--r-- | internal/service/scan.go | 101 |
1 files changed, 0 insertions, 101 deletions
diff --git a/internal/service/scan.go b/internal/service/scan.go deleted file mode 100644 index da5c54f..0000000 --- a/internal/service/scan.go +++ /dev/null @@ -1,101 +0,0 @@ -package service - -import ( - "context" - "errors" - "log/slog" - "sync" - "time" - - "codeberg.org/snonux/player/internal/clock" - "codeberg.org/snonux/player/internal/model" - "codeberg.org/snonux/player/internal/scanner" -) - -// scanService handles triggering and tracking media library scans. -type scanService struct { - scanner scanner.Scanner - mediaRoot string - clock clock.Clock - logger *slog.Logger - mu sync.Mutex - scanCancel context.CancelFunc - progress *model.ScanProgress - appCtx context.Context // application-level context used to propagate shutdown cancellation - doneCh chan<- struct{} -} - -// NewScanService creates a ScanService. -func NewScanService(appCtx context.Context, sc scanner.Scanner, mediaRoot string, clk clock.Clock, logger *slog.Logger) *scanService { - if logger == nil { - logger = slog.Default() - } - return &scanService{ - scanner: sc, - mediaRoot: mediaRoot, - clock: clk, - logger: logger, - appCtx: appCtx, - } -} - -func (s *scanService) TriggerRescan(ctx context.Context) error { - if s.scanner == nil { - return errors.New("scanner not configured") - } - - s.mu.Lock() - if s.scanCancel != nil { - s.scanCancel() - } - // Derive the scan context from the application-level context so that - // cancellation propagates on server exit, while still applying a 30-minute timeout. - scanCtx, cancel := context.WithTimeout(s.appCtx, 30*time.Minute) - s.scanCancel = cancel - progress := &model.ScanProgress{} - progress.Start(0) - s.progress = progress - s.mu.Unlock() - - go func() { - defer cancel() - defer s.notifyDone() - defer func() { - if err := handleWorkerPanic(s.logger, "rescan", recover()); err != nil { - progress.Done(err) - } - }() - err := s.scanner.Scan(scanCtx, s.mediaRoot, progress) - if err == nil { - err = scanCtx.Err() - } - if err != nil { - progress.Done(err) - s.logger.Error("rescan failed", "err", err) - } else { - progress.Done(nil) - s.logger.Info("rescan completed") - } - }() - return nil -} - -func (s *scanService) ScanProgress(ctx context.Context) model.ScanProgress { - s.mu.Lock() - progress := s.progress - s.mu.Unlock() - if progress == nil { - return model.ScanProgress{} - } - return progress.Copy() -} - -func (s *scanService) notifyDone() { - if s.doneCh == nil { - return - } - select { - case s.doneCh <- struct{}{}: - default: - } -} |
