Skip to content

Commit 758be33

Browse files
authored
Don't wait for websocket to close on Shard disconnect (#3369)
1 parent c0fb264 commit 758be33

File tree

3 files changed

+15
-26
lines changed

3 files changed

+15
-26
lines changed

src/gateway/sharding/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,8 @@ async fn connect(base_url: &str, compression: TransportCompression) -> Result<Ws
698698
Error::Gateway(GatewayError::BuildingUrl)
699699
})?;
700700

701-
WsClient::connect(url, compression).await
701+
let client = WsClient::connect(url, compression).await?;
702+
Ok(client)
702703
}
703704

704705
struct ResumeMetadata {

src/gateway/sharding/shard_runner.rs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::sync::Arc;
33
use dashmap::DashMap;
44
use dashmap::try_result::TryResult;
55
use futures::channel::mpsc::{self, UnboundedReceiver as Receiver, UnboundedSender as Sender};
6-
use tokio_tungstenite::tungstenite;
76
use tokio_tungstenite::tungstenite::error::Error as TungsteniteError;
87
use tokio_tungstenite::tungstenite::protocol::frame::CloseFrame;
98
#[cfg(feature = "tracing_instrument")]
@@ -234,7 +233,13 @@ impl ShardRunner {
234233
}
235234
}
236235

237-
// Shuts down the WebSocket client.
236+
/// Shuts down the WebSocket client.
237+
///
238+
/// The Shard will be in an indeterminate state after this call, especially if called after
239+
/// error.
240+
///
241+
/// Therefore, the only correct code path is to exit out of the ShardRunner loop and discard the
242+
/// WebSocket client entirely.
238243
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
239244
async fn shutdown(&mut self, close_code: u16) {
240245
debug!("[ShardRunner {:?}] Shutting down.", self.shard.shard_info());
@@ -248,22 +253,6 @@ impl ShardRunner {
248253
}))
249254
.await,
250255
);
251-
252-
// In return, we wait for either a Close Frame response, or an error, after which this WS
253-
// is deemed disconnected from Discord.
254-
loop {
255-
match self.shard.client.next().await {
256-
Some(Ok(tungstenite::Message::Close(_))) => return,
257-
Some(Err(_)) => {
258-
warn!(
259-
"[ShardRunner {:?}] Received an error awaiting close frame",
260-
self.shard.shard_info(),
261-
);
262-
return;
263-
},
264-
_ => {},
265-
}
266-
}
267256
}
268257

269258
#[cfg(feature = "voice")]

src/gateway/ws.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use zstd_safe::{DStream as ZstdInflater, InBuffer, OutBuffer};
2020

2121
use super::{ActivityData, ChunkGuildFilter, GatewayError, PresenceData, TransportCompression};
2222
use crate::constants::{self, Opcode};
23+
use crate::internal::prelude::*;
2324
use crate::model::event::GatewayEvent;
2425
use crate::model::gateway::{GatewayIntents, ShardInfo};
2526
#[cfg(feature = "voice")]
@@ -236,7 +237,10 @@ pub struct WsClient {
236237
const TIMEOUT: Duration = Duration::from_millis(500);
237238

238239
impl WsClient {
239-
pub(crate) async fn connect(url: Url, compression: TransportCompression) -> Result<Self> {
240+
pub(crate) async fn connect(
241+
url: Url,
242+
compression: TransportCompression,
243+
) -> StdResult<Self, WsError> {
240244
let config = {
241245
let mut config = WebSocketConfig::default();
242246
config.max_message_size = None;
@@ -288,13 +292,8 @@ impl WsClient {
288292
Ok(())
289293
}
290294

291-
/// Delegate to `StreamExt::next`
292-
pub(crate) async fn next(&mut self) -> Option<std::result::Result<Message, WsError>> {
293-
self.stream.next().await
294-
}
295-
296295
/// Delegate to `WebSocketStream::close`
297-
pub(crate) async fn close(&mut self, msg: Option<CloseFrame>) -> Result<()> {
296+
pub(crate) async fn close(&mut self, msg: Option<CloseFrame>) -> StdResult<(), WsError> {
298297
self.stream.close(msg).await?;
299298
Ok(())
300299
}

0 commit comments

Comments
 (0)