Skip to content

Commit 812c972

Browse files
fix: handle dealer reconnect in-place without restarting spirc
Symptoms observed in logs: WARN librespot_core::dealer Websocket peer does not respond. WARN librespot_connect::spirc unexpected shutdown WARN librespot Spirc shut down unexpectedly When the dealer websocket drops (peer timeout or TLS close_notify), SpircTask broke out of its event loop so main.rs could tear down and recreate the entire Spirc. This caused playback to stop on every transient websocket drop — even though the dealer already auto-reconnects the websocket. The subscription streams survive reconnects because they are registered on the shared DealerShared instance. After reconnect, the server pushes a new connection_id which handle_connection_id_update already handles. Changes: reconnect_rx.changed() logs and continues instead of breaking. handle_connection_id_update errors are non-fatal (logged, not breaking). After fix — 6 days of logs (Mar 14-20) showing ~20 dealer reconnects handled in-place without restarting spirc or stopping playback: Mar 16 05:06 — "Dealer reconnected; awaiting new connection_id." Mar 16 05:06 — "re-registering with active playback state: Paused { ... }" [no restart, no "Spirc shut down unexpectedly"] Mar 18 12:14 — "Dealer reconnected; awaiting new connection_id." Mar 18 12:14 — "re-registering with active playback state: Playing { ... }" [playback continued uninterrupted] Mar 19 — 9 dealer reconnects in one day, all handled in-place Summary: 0 spirc restarts from dealer reconnects (vs ~1/day before fix). Co-authored-by: Copilot <[email protected]>
1 parent 34d2fd9 commit 812c972

1 file changed

Lines changed: 6 additions & 5 deletions

File tree

connect/src/spirc.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,6 @@ impl SpircTask {
480480
connection_id_update,
481481
match |connection_id| if let Err(why) = self.handle_connection_id_update(connection_id).await {
482482
error!("failed handling connection id update: {why}");
483-
break;
484483
}
485484
},
486485
// main dealer update of any remote device updates
@@ -588,11 +587,13 @@ impl SpircTask {
588587
}
589588
}
590589
},
591-
// dealer reconnected after a connection loss — our subscription
592-
// streams are stale, so break out and let main.rs re-create spirc
590+
// Dealer reconnected after a connection loss. Our subscription
591+
// streams survive because they're registered on the shared
592+
// DealerShared — the new websocket dispatches through the same
593+
// handlers. A new connection_id will arrive via
594+
// connection_id_update and re-register our device state.
593595
Ok(()) = reconnect_rx.changed() => {
594-
warn!("Dealer reconnected; restarting spirc to refresh subscriptions.");
595-
break;
596+
info!("Dealer reconnected; awaiting new connection_id.");
596597
},
597598
else => break
598599
}

0 commit comments

Comments
 (0)