fix(startup): sweep open scrobbles before accepting playback

The open-scrobble sweep was queued in the deferred background-init list,
which runs concurrently with the HTTP listener; a resume immediately after
restart could start new scrobbles before the previous process's open
sessions were stopped, leaving overlapping/stale scrobbles on remote
providers. Run the sweep synchronously before the listener starts, bounded
by a 30s timeout so an unreachable provider can't hang startup (the heavier
non-critical init stays deferred).

Addresses PR #21 review (P2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Quick
2026-05-28 20:26:15 -04:00
co-authored by Claude Opus 4.8
parent 8b82906c7b
commit 7161c86f73
+13 -5
View File
@@ -1023,11 +1023,6 @@ func main() {
WithMatcher(historyimport.NewMatcher(historyRepo)).
WithWatchState(watchstate.NewService(userStoreProvider).WithStableIdentityResolver(historyIdentity)).
WithUserStoreProvider(userStoreProvider)
backgroundInit = append(backgroundInit, func(ctx context.Context) {
if err := watchProviderService.SweepOpenScrobbles(ctx); err != nil {
slog.Warn("failed to sweep open watch provider scrobbles", "error", err)
}
})
}
deps.SessionMgr = sessionMgr
deps.PlaybackRealtimeHub = playback.NewRealtimeHub()
@@ -1683,6 +1678,19 @@ func main() {
}()
}
// Stop scrobble sessions left open by the previous process BEFORE the
// listener accepts playback requests, so a resume immediately after a
// restart doesn't create overlapping/stale scrobbles on remote providers.
// Bounded by a timeout so an unreachable provider can't hang startup (which
// is why the rest of non-critical init stays deferred below).
if watchProviderService != nil {
sweepCtx, cancelSweep := context.WithTimeout(appCtx, 30*time.Second)
if err := watchProviderService.SweepOpenScrobbles(sweepCtx); err != nil {
slog.Warn("failed to sweep open watch provider scrobbles", "error", err)
}
cancelSweep()
}
errCh := make(chan error, 2)
go func() {
slog.Info("HTTP server listening", "addr", cfg.Server.Listen)