Driver: Fix multiple disconnect events on leave (#233)

Fixes behaviour where a Driver which was asked to leave an active call would receive the disconnect event several times: once when we started the disconnect, and once again when Discord killed the WS client.
This commit is contained in:
Kyle Simpson
2024-03-19 08:28:56 +00:00
committed by GitHub
parent 58f5c89f92
commit a5d9b58e94
2 changed files with 20 additions and 11 deletions

View File

@@ -109,7 +109,7 @@ async fn runner(mut config: Config, rx: Receiver<CoreMessage>, tx: Sender<CoreMe
drop(interconnect.events.send(EventMessage::FireCoreEvent( drop(interconnect.events.send(EventMessage::FireCoreEvent(
CoreContext::DriverDisconnect(InternalDisconnect { CoreContext::DriverDisconnect(InternalDisconnect {
kind: DisconnectKind::Runtime, kind: DisconnectKind::Runtime,
reason: None, reason: Some(DisconnectReason::Requested),
info: conn.info.clone(), info: conn.info.clone(),
}), }),
))); )));
@@ -120,14 +120,18 @@ async fn runner(mut config: Config, rx: Receiver<CoreMessage>, tx: Sender<CoreMe
// (i.e., prevent users from mistakenly trying to reconnect for an *old* dead conn). // (i.e., prevent users from mistakenly trying to reconnect for an *old* dead conn).
// if it *is* a match, the conn needs to die! // if it *is* a match, the conn needs to die!
// (as the WS channel has truly given up the ghost). // (as the WS channel has truly given up the ghost).
if ws_idx == attempt_idx { let conn = if ws_idx == attempt_idx {
connection = None;
drop(interconnect.mixer.send(MixerMessage::DropConn)); drop(interconnect.mixer.send(MixerMessage::DropConn));
drop(interconnect.mixer.send(MixerMessage::RebuildEncoder)); drop(interconnect.mixer.send(MixerMessage::RebuildEncoder));
connection.take()
} else { } else {
reason = None; reason = None;
} None
};
// Conn may have been unset earlier (i.e., in a deliberate disconnect).
// If so, do not repropagate/repeat the disconnect event.
if conn.is_some() {
drop(interconnect.events.send(EventMessage::FireCoreEvent( drop(interconnect.events.send(EventMessage::FireCoreEvent(
CoreContext::DriverDisconnect(InternalDisconnect { CoreContext::DriverDisconnect(InternalDisconnect {
kind: DisconnectKind::Runtime, kind: DisconnectKind::Runtime,
@@ -135,6 +139,7 @@ async fn runner(mut config: Config, rx: Receiver<CoreMessage>, tx: Sender<CoreMe
info: ws_info, info: ws_info,
}), }),
))); )));
}
}, },
CoreMessage::SetTrack(s) => { CoreMessage::SetTrack(s) => {
drop(interconnect.mixer.send(MixerMessage::SetTrack(s))); drop(interconnect.mixer.send(MixerMessage::SetTrack(s)));

View File

@@ -75,6 +75,10 @@ pub enum DisconnectReason {
ProtocolViolation, ProtocolViolation,
/// A voice connection was not established in the specified time. /// A voice connection was not established in the specified time.
TimedOut, TimedOut,
/// The call was manually disconnected by a user command, e.g. [`Driver::leave`].
///
/// [`Driver::leave`]: crate::driver::Driver::leave
Requested,
/// The Websocket connection was closed by Discord. /// The Websocket connection was closed by Discord.
/// ///
/// This typically indicates that the voice session has expired, /// This typically indicates that the voice session has expired,