aboutsummaryrefslogtreecommitdiff
path: root/src/gateway
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
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')
-rw-r--r--src/gateway/mod.rs10
-rw-r--r--src/gateway/shard.rs44
2 files changed, 27 insertions, 27 deletions
diff --git a/src/gateway/mod.rs b/src/gateway/mod.rs
index 7e4e2b0..a6de656 100644
--- a/src/gateway/mod.rs
+++ b/src/gateway/mod.rs
@@ -148,9 +148,15 @@ impl ConnectionStage {
}
pub enum ShardAction {
- Autoreconnect,
Heartbeat,
Identify,
- Reconnect,
+ Reconnect(ReconnectType),
+}
+
+/// The type of reconnection that should be performed.
+pub enum ReconnectType {
+ /// Indicator that a new connection should be made by sending an IDENTIFY.
+ Reidentify,
+ /// Indicator that a new connection should be made by sending a RESUME.
Resume,
}
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.