2 months ago
61c0e6cAdd an async stale-guarded stem-set download orchestrator, a testable playback reconnect coordinator, and an atomic source-swap command so a remote streaming source can recover from transient mid-song failures without an audible position jump. - errors: add RemoteErrorKind::StaleRequest (never retried) for the stale-guard abort path. - playback_source: add ensure_remote_stem_set_cached_guarded which checks a Fn() -> bool stale guard before each stem download and before the atomic-rename phase, discarding temps and returning StaleRequest when the active request has moved on. The playback path now uses the guarded variant. - reconnect: new services::reconnect module with a bounded-retry ReconnectCoordinator driven by injected closures (re-resolve, seek, credential refresh, stale guard, event sink, sleep). Reuses the shared net_policy full-jitter backoff. Emits Reconnecting/Resync/Failed events; classifies via RemoteErrorKind so non-transient errors abort immediately and credential-expired errors trigger a refresh before the next attempt. - coordinator: add ReplaceStreamingSource PlaybackCommand and handler that swaps the active streaming source under the playback mutex in one critical section, sets render_frame to the preserved position, seeks the new consumers, and marks buffering. Stale requests (user skipped) no-op. - playback: wire the reconnect coordinator into the fetch event thread. ConsecutiveFailures triggers a transient reconnect; UrlExpired triggers a credential-expired reconnect; RangeNotSupported keeps the full-file fallback. On success the new source is sent to the coordinator for atomic swap; on failure a remote-playback-failed event and a playback-error are surfaced. - playback: add remote-playback-reconnect / remote-playback-resync / remote-playback-failed IPC events and payload structs. - docs: document the three new events and the internal ReplaceStreamingSource command in the playback contract. Tests: 8 reconnect unit tests (transient retry, budget exhaustion, non-transient abort, credential refresh, resync, stale guard, cache fast path, classification) and 3 stale-guard stem-set tests (rename abort, mid-set cancellation, current-request success).
Parent87b2055