Skip to content

Commit 8c4e3a1

Browse files
GnomedDevmkrasnitski
authored andcommitted
Don't wait for websocket to close on Shard disconnect (serenity-rs#3369)
1 parent 9ff0f94 commit 8c4e3a1

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")]
@@ -235,7 +234,13 @@ impl ShardRunner {
235234
}
236235
}
237236

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

270259
#[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)