refactor(playlists): improve evaluator efficiency and logging

- Use time.NewTimer instead of time.After to avoid timer leaks
- Create admin context once per batch instead of per playlist
- Pass context to log calls for consistent request-scoped fields
This commit is contained in:
Deluan 2026-03-23 20:25:31 -04:00
parent 03b813a2f6
commit 359ea3c61c
2 changed files with 13 additions and 15 deletions

View file

@ -69,31 +69,29 @@ func (e *smartPlaylistEvaluator) run() {
}
func (e *smartPlaylistEvaluator) waitSignal(timeout time.Duration) {
timer := time.NewTimer(timeout)
defer timer.Stop()
select {
case <-time.After(timeout):
case <-timer.C:
case <-e.wakeSignal:
}
}
func (e *smartPlaylistEvaluator) processBatch(batch []string) {
log.Debug("Evaluating smart playlists in background", "count", len(batch))
for _, id := range batch {
e.doEvaluate(id)
}
}
func (e *smartPlaylistEvaluator) doEvaluate(id string) {
// Use admin context so userFilter() returns all playlists.
// Evaluate() internally uses pls.OwnerID for annotation JOINs.
ctx := auth.WithAdminUser(context.TODO(), e.ds)
start := time.Now()
err := e.ds.Playlist(ctx).Evaluate(id)
if err != nil {
log.Error("Error evaluating smart playlist in background", "id", id, err)
return
log.Debug(ctx, "Evaluating smart playlists in background", "count", len(batch))
for _, id := range batch {
start := time.Now()
err := e.ds.Playlist(ctx).Evaluate(id)
if err != nil {
log.Error(ctx, "Error evaluating smart playlist in background", "id", id, err)
continue
}
log.Debug(ctx, "Smart playlist evaluation complete", "id", id, "elapsed", time.Since(start))
}
log.Debug("Background smart playlist evaluation complete", "id", id, "elapsed", time.Since(start))
}
// NoopSmartPlaylistEvaluator returns an evaluator that does nothing.

View file

@ -109,7 +109,7 @@ func (p *phasePlaylists) processPlaylistsInFolder(folder *model.Folder) (*model.
}
if pls.IsSmartPlaylist() {
p.spe.Enqueue(pls.ID)
log.Debug("Scanner: Imported smart playlist", "name", pls.Name, "lastUpdated", pls.UpdatedAt, "path", pls.Path, "elapsed", time.Since(started))
log.Debug(p.ctx, "Scanner: Imported smart playlist", "name", pls.Name, "lastUpdated", pls.UpdatedAt, "path", pls.Path, "elapsed", time.Since(started))
} else {
log.Debug("Scanner: Imported playlist", "name", pls.Name, "lastUpdated", pls.UpdatedAt, "path", pls.Path, "numTracks", len(pls.Tracks), "elapsed", time.Since(started))
}