aboutsummaryrefslogtreecommitdiff
path: root/src/gateway/shard.rs
diff options
context:
space:
mode:
authorZeyla Hellyer <[email protected]>2017-12-16 20:49:01 -0800
committerZeyla Hellyer <[email protected]>2017-12-16 20:49:01 -0800
commite6788838556d13d4a4f19253ce297ca2f72168ee (patch)
tree72b5e315257fc609664e65eaf0c3992b19a51105 /src/gateway/shard.rs
parentAvoid an unwrap in args::parse_quotes (diff)
downloadserenity-e6788838556d13d4a4f19253ce297ca2f72168ee.tar.xz
serenity-e6788838556d13d4a4f19253ce297ca2f72168ee.zip
Fix shards attempting to re-identify on their own
Fix shards by taking away their responsibility to re-identify, instead shutting down shard runners and going through the shard queuer to restart a shard runner and its associated shard. This fixes the case where a running shard's session invalidates and re-IDENTIFYs within 5 seconds before queued shard starts, causing a cascading failure of sessions for new shards.
Diffstat (limited to 'src/gateway/shard.rs')
-rw-r--r--src/gateway/shard.rs44
1 files changed, 19 insertions, 25 deletions
diff --git a/src/gateway/shard.rs b/src/gateway/shard.rs
index c00affc..75dc147 100644
--- a/src/gateway/shard.rs
+++ b/src/gateway/shard.rs
@@ -12,6 +12,7 @@ use super::{
CurrentPresence,
ShardAction,
GatewayError,
+ ReconnectType,
WsClient,
WebSocketGatewayClientExt,
};
@@ -450,7 +451,7 @@ impl Shard {
self.shard_info
);
- return Ok(Some(ShardAction::Autoreconnect));
+ return Ok(Some(ShardAction::Reconnect(self.reconnection_type())));
}
}
@@ -483,7 +484,7 @@ impl Shard {
debug!("[Shard {:?}] Received late Hello; autoreconnecting",
self.shard_info);
- ShardAction::Autoreconnect
+ ShardAction::Reconnect(self.reconnection_type())
}))
},
Ok(GatewayEvent::InvalidateSession(resumable)) => {
@@ -493,12 +494,14 @@ impl Shard {
);
Ok(Some(if resumable {
- ShardAction::Resume
+ ShardAction::Reconnect(ReconnectType::Resume)
} else {
- ShardAction::Reconnect
+ ShardAction::Reconnect(ReconnectType::Reidentify)
}))
},
- Ok(GatewayEvent::Reconnect) => Ok(Some(ShardAction::Reconnect)),
+ Ok(GatewayEvent::Reconnect) => {
+ Ok(Some(ShardAction::Reconnect(ReconnectType::Reidentify)))
+ },
Err(Error::Gateway(GatewayError::Closed(ref data))) => {
let num = data.as_ref().map(|d| d.status_code);
let clean = num == Some(1000);
@@ -572,9 +575,9 @@ impl Shard {
}).unwrap_or(true);
Ok(Some(if resume {
- ShardAction::Resume
+ ShardAction::Reconnect(ReconnectType::Resume)
} else {
- ShardAction::Reconnect
+ ShardAction::Reconnect(ReconnectType::Reidentify)
}))
},
Err(Error::WebSocket(ref why)) => {
@@ -590,7 +593,7 @@ impl Shard {
info!("[Shard {:?}] Will attempt to auto-reconnect",
self.shard_info);
- Ok(Some(ShardAction::Autoreconnect))
+ Ok(Some(ShardAction::Reconnect(self.reconnection_type())))
},
_ => Ok(None),
}
@@ -700,29 +703,20 @@ impl Shard {
///
/// [`ConnectionStage::Connecting`]: ../../../gateway/enum.ConnectionStage.html#variant.Connecting
/// [`session_id`]: ../../../gateway/struct.Shard.html#method.session_id
- pub fn autoreconnect(&mut self) -> Result<()> {
+ pub fn should_reconnect(&mut self) -> Option<ReconnectType> {
if self.stage == ConnectionStage::Connecting {
- return Ok(());
+ return None;
}
- if self.session_id().is_some() {
- debug!(
- "[Shard {:?}] Autoreconnector choosing to resume",
- self.shard_info,
- );
+ Some(self.reconnection_type())
+ }
- self.resume()?;
+ pub fn reconnection_type(&self) -> ReconnectType {
+ if self.session_id().is_some() {
+ ReconnectType::Resume
} else {
- debug!(
- "[Shard {:?}] Autoreconnector choosing to reconnect",
- self.shard_info,
- );
-
- self.reconnect()?;
+ ReconnectType::Reidentify
}
- self.shutdown = true;
-
- Ok(())
}
/// Requests that one or multiple [`Guild`]s be chunked.