Skip to content

Commit

Permalink
Rearrange gateway bridge module into sharding and spruce up docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrasnitski committed Aug 17, 2024
1 parent 8a569e0 commit e9d1f85
Show file tree
Hide file tree
Showing 11 changed files with 293 additions and 354 deletions.
20 changes: 0 additions & 20 deletions src/gateway/bridge/event.rs

This file was deleted.

114 changes: 0 additions & 114 deletions src/gateway/bridge/mod.rs

This file was deleted.

53 changes: 0 additions & 53 deletions src/gateway/bridge/shard_runner_message.rs

This file was deleted.

20 changes: 18 additions & 2 deletions src/gateway/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,24 @@
//! events to handlers and starting sharded gateway connections is handled directly by the client.
//! In addition, the client automatically handles caching via the [`Cache`] struct.
//!
//! # Sharding
//!
//! If you do not require sharding - such as for a small bot - then use [`Client::start`]. If you
//! don't know what sharding is, refer to the [`sharding`] module documentation.
//!
//! There are a few methods of sharding available:
//! - [`Client::start_autosharded`]: retrieves the number of shards Discord recommends using from
//! the API, and then automatically starts that number of shards.
//! - [`Client::start_shard`]: starts a single shard for use in the instance, handled by the
//! instance of the Client. Use this if you only want 1 shard handled by this instance.
//! - [`Client::start_shards`]: starts all shards in this instance. This is best for when you want a
//! completely shared State.
//! - [`Client::start_shard_range`]: start a range of shards within this instance. This should be
//! used when you, for example, want to split 10 shards across 3 instances.
//!
//! Click [here][Client#examples] for an example on how to use a [`Client`].
//!
//! [`sharding`]: crate::gateway::sharding

mod context;
pub(crate) mod dispatch;
Expand Down Expand Up @@ -357,7 +374,7 @@ impl IntoFuture for ClientBuilder {

/// The Client is the way to be able to start sending authenticated requests over the REST API, as
/// well as initializing a WebSocket connection through [`Shard`]s. Refer to the [documentation on
/// using sharding][sharding docs] for more information.
/// using sharding][super::sharding] for more information.
///
/// # Event Handlers
///
Expand Down Expand Up @@ -399,7 +416,6 @@ impl IntoFuture for ClientBuilder {
///
/// [`Shard`]: crate::gateway::Shard
/// [`Event::MessageCreate`]: crate::model::event::Event::MessageCreate
/// [sharding docs]: crate::gateway#sharding
pub struct Client {
data: Arc<dyn std::any::Any + Send + Sync>,
/// A HashMap of all shards instantiated by the Client.
Expand Down
144 changes: 14 additions & 130 deletions src/gateway/mod.rs
Original file line number Diff line number Diff line change
@@ -1,60 +1,30 @@
//! The gateway module contains the pieces - primarily the `Shard` - responsible for maintaining a
//! WebSocket connection with Discord.
//! Contains the necessary plumping for maintaining a connection with Discord.
//! The primary building blocks are the [`Client`] and the [`Shard`].
//!
//! A shard is an interface for the lower-level receiver and sender. It provides what can otherwise
//! be thought of as "sugar methods". A shard represents a single connection to Discord. You can
//! make use of a method named "sharding" to have multiple shards, potentially offloading some
//! server load to another server(s).
//! The [`Client`] is a high-level interface that takes care of communicating with Discord's REST
//! API as well as receiving and dispatching events from the gateway using a WebSocket client.
//!
//! # Sharding
//!
//! Sharding is a method to split portions of bots into separate processes. This is an enforced
//! strategy by Discord once a bot reaches a certain number of guilds (2500). Once this number is
//! reached, a bot must be sharded in a way that only 2500 guilds maximum may be allocated per
//! shard.
//!
//! The "recommended" number of guilds per shard is _around_ 1000. Sharding can be useful for
//! splitting processes across separate servers. Often you may want some or all shards to be in the
//! same process, allowing for a shared State. This is possible through this library.
//!
//! See [Discord's documentation][docs] for more information.
//!
//! If you do not require sharding - such as for a small bot - then use [`Client::start`].
//!
//! There are a few methods of sharding available:
//! - [`Client::start_autosharded`]: retrieves the number of shards Discord recommends using from
//! the API, and then automatically starts that number of shards.
//! - [`Client::start_shard`]: starts a single shard for use in the instance, handled by the
//! instance of the Client. Use this if you only want 1 shard handled by this instance.
//! - [`Client::start_shards`]: starts all shards in this instance. This is best for when you want a
//! completely shared State.
//! - [`Client::start_shard_range`]: start a range of shards within this instance. This should be
//! used when you, for example, want to split 10 shards across 3 instances.
//!
//! [`Client`]: crate::Client
//! [`Client::start`]: crate::Client::start
//! [`Client::start_autosharded`]: crate::Client::start_autosharded
//! [`Client::start_shard`]: crate::Client::start_shard
//! [`Client::start_shard_range`]: crate::Client::start_shard_range
//! [`Client::start_shards`]: crate::Client::start_shards
//! [docs]: https://discordapp.com/developers/docs/topics/gateway#sharding
//! On the other hand, the [`Shard`] is a low-level receiver and sender representing a single
//! connection to Discord. The client will handle shard management automatically for you, so you
//! should only care about using it directly if you really need to. See the [`sharding`] module for
//! details and documentation.

mod bridge;
pub mod client;
mod error;
mod shard;
pub mod sharding;
#[cfg(feature = "voice")]
mod voice;
mod ws;

use std::fmt;

#[cfg(feature = "http")]
use reqwest::IntoUrl;
use reqwest::Url;

pub use self::bridge::*;
pub use self::client::*;
pub use self::error::Error as GatewayError;
pub use self::shard::Shard;
pub use self::sharding::*;
#[cfg(feature = "voice")]
pub use self::voice::VoiceGatewayManager;
pub use self::ws::WsClient;
use crate::internal::prelude::*;
use crate::model::gateway::{Activity, ActivityType};
Expand Down Expand Up @@ -169,92 +139,6 @@ impl From<Activity> for ActivityData {
}
}

/// Indicates the current connection stage of a [`Shard`].
///
/// This can be useful for knowing which shards are currently "down"/"up".
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[non_exhaustive]
pub enum ConnectionStage {
/// Indicator that the [`Shard`] is normally connected and is not in, e.g., a resume phase.
Connected,
/// Indicator that the [`Shard`] is connecting and is in, e.g., a resume phase.
Connecting,
/// Indicator that the [`Shard`] is fully disconnected and is not in a reconnecting phase.
Disconnected,
/// Indicator that the [`Shard`] is currently initiating a handshake.
Handshake,
/// Indicator that the [`Shard`] has sent an IDENTIFY packet and is awaiting a READY packet.
Identifying,
/// Indicator that the [`Shard`] has sent a RESUME packet and is awaiting a RESUMED packet.
Resuming,
}

impl ConnectionStage {
/// Whether the stage is a form of connecting.
///
/// This will return `true` on:
/// - [`Connecting`][`ConnectionStage::Connecting`]
/// - [`Handshake`][`ConnectionStage::Handshake`]
/// - [`Identifying`][`ConnectionStage::Identifying`]
/// - [`Resuming`][`ConnectionStage::Resuming`]
///
/// All other variants will return `false`.
///
/// # Examples
///
/// Assert that [`ConnectionStage::Identifying`] is a connecting stage:
///
/// ```rust
/// use serenity::gateway::ConnectionStage;
///
/// assert!(ConnectionStage::Identifying.is_connecting());
/// ```
///
/// Assert that [`ConnectionStage::Connected`] is _not_ a connecting stage:
///
/// ```rust
/// use serenity::gateway::ConnectionStage;
///
/// assert!(!ConnectionStage::Connected.is_connecting());
/// ```
#[must_use]
pub fn is_connecting(self) -> bool {
use self::ConnectionStage::{Connecting, Handshake, Identifying, Resuming};
matches!(self, Connecting | Handshake | Identifying | Resuming)
}
}

impl fmt::Display for ConnectionStage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match *self {
Self::Connected => "connected",
Self::Connecting => "connecting",
Self::Disconnected => "disconnected",
Self::Handshake => "handshaking",
Self::Identifying => "identifying",
Self::Resuming => "resuming",
})
}
}

#[derive(Debug)]
#[non_exhaustive]
pub enum ShardAction {
Heartbeat,
Identify,
Reconnect(ReconnectType),
}

/// The type of reconnection that should be performed.
#[derive(Debug)]
#[non_exhaustive]
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,
}

/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#request-guild-members).
#[derive(Clone, Debug)]
pub enum ChunkGuildFilter {
Expand Down
Loading

0 comments on commit e9d1f85

Please sign in to comment.