Skip to content

Commit c44f649

Browse files
GnomedDevmkrasnitski
authored andcommitted
Implement ShardManager::get_shutdown_trigger (serenity-rs#3353)
1 parent 86a9ddc commit c44f649

File tree

2 files changed

+12
-79
lines changed

2 files changed

+12
-79
lines changed

src/gateway/client/mod.rs

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -392,35 +392,9 @@ impl IntoFuture for ClientBuilder {
392392
/// [`Event::MessageCreate`]: crate::model::event::Event::MessageCreate
393393
pub struct Client {
394394
data: Arc<dyn std::any::Any + Send + Sync>,
395-
/// A HashMap of all shards instantiated by the Client.
395+
/// The shard manager for the client.
396396
///
397-
/// The key is the shard ID and the value is the shard itself.
398-
///
399-
/// # Examples
400-
///
401-
/// If you call [`client.start_shard(3, 5)`][`Client::start_shard`], this HashMap will only
402-
/// ever contain a single key of `3`, as that's the only Shard the client is responsible for.
403-
///
404-
/// If you call [`client.start_shards(10)`][`Client::start_shards`], this HashMap will contain
405-
/// keys 0 through 9, one for each shard handled by the client.
406-
///
407-
/// Printing the number of shards currently instantiated by the client every 5 seconds:
408-
///
409-
/// ```rust,no_run
410-
/// # use serenity::prelude::*;
411-
/// # use std::time::Duration;
412-
/// #
413-
/// # fn run(client: Client) {
414-
/// tokio::spawn(async move {
415-
/// loop {
416-
/// let count = client.shard_manager.shards_instantiated().len();
417-
/// println!("Shard count instantiated: {}", count);
418-
///
419-
/// tokio::time::sleep(Duration::from_millis(5000)).await;
420-
/// }
421-
/// });
422-
/// # }
423-
/// ```
397+
/// This is the brains, managing shards (websocket connections) and bot lifecycle.
424398
pub shard_manager: ShardManager,
425399
/// The voice manager for the client.
426400
///

src/gateway/sharding/shard_manager.rs

Lines changed: 10 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ impl ShardManager {
118118
}
119119
}
120120

121+
/// Retrieves a function which can be used to shut down the ShardManager later.
122+
///
123+
/// This function will return `true` if the ShardManager has successfully been
124+
/// notified to shut down, or false if it has already shut down and been dropped.
125+
pub fn get_shutdown_trigger(&self) -> impl FnOnce() -> bool + Send + use<> {
126+
let manager_tx = self.manager_tx.clone();
127+
move || manager_tx.unbounded_send(ShardManagerMessage::Quit(Ok(()))).is_ok()
128+
}
129+
121130
/// The main interface for starting the management of shards. Initializes the shards by
122131
/// queueing them for starting, and then listens for [`ShardManagerMessage`]s in a loop.
123132
///
@@ -161,7 +170,7 @@ impl ShardManager {
161170
/// Note that this queues all shards but does not actually start them. To start the manager's
162171
/// event loop and dispatch [`ShardRunner`]s as they get queued, call [`Self::run`] instead.
163172
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
164-
pub fn initialize(&mut self, shard_index: u16, shard_init: u16, shard_total: NonZeroU16) {
173+
fn initialize(&mut self, shard_index: u16, shard_init: u16, shard_total: NonZeroU16) {
165174
let shard_to = shard_index + shard_init;
166175

167176
self.shard_total = shard_total;
@@ -177,39 +186,6 @@ impl ShardManager {
177186
self.queue.push_back(shard_id);
178187
}
179188

180-
/// Restarts a shard runner.
181-
///
182-
/// Sends a shutdown signal to a shard's associated [`ShardRunner`], and then queues an
183-
/// initialization of a new shard runner for the same shard.
184-
///
185-
/// [`ShardRunner`]: super::ShardRunner
186-
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
187-
pub fn restart(&mut self, shard_id: ShardId) {
188-
info!("Restarting shard {shard_id}");
189-
190-
if let Some((_, (_, tx))) = self.runners.remove(&shard_id) {
191-
if let Err(why) = tx.unbounded_send(ShardRunnerMessage::Restart) {
192-
warn!("Failed to send restart signal to shard {shard_id}: {why:?}");
193-
}
194-
}
195-
}
196-
197-
/// Attempts to shut down the shard runner by Id.
198-
///
199-
/// **Note**: If the receiving end of an mpsc channel - owned by the shard runner - no longer
200-
/// exists, then the shard runner will not know it should shut down. This _should never happen_.
201-
/// It may already be stopped.
202-
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
203-
pub fn shutdown(&mut self, shard_id: ShardId, code: u16) {
204-
info!("Shutting down shard {}", shard_id);
205-
206-
if let Some((_, (_, tx))) = self.runners.remove(&shard_id) {
207-
if let Err(why) = tx.unbounded_send(ShardRunnerMessage::Shutdown(code)) {
208-
warn!("Failed to send shutdown signal to shard {shard_id}: {why:?}");
209-
}
210-
}
211-
}
212-
213189
// This function assumes that each of the shard ids are bucketed separately according to
214190
// `max_concurrency`. If this assumption is violated, you will likely get ratelimited.
215191
//
@@ -291,23 +267,6 @@ impl ShardManager {
291267
Ok(())
292268
}
293269

294-
/// Returns whether the shard manager contains an active instance of a shard runner responsible
295-
/// for the given ID.
296-
///
297-
/// If a shard has been queued but has not yet been initiated, then this will return `false`.
298-
#[must_use]
299-
pub fn has(&self, shard_id: ShardId) -> bool {
300-
self.runners.contains_key(&shard_id)
301-
}
302-
303-
/// Returns the [`ShardId`]s of the shards that have been instantiated and currently have a
304-
/// valid [`ShardRunner`].
305-
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
306-
#[must_use]
307-
pub fn shards_instantiated(&self) -> Vec<ShardId> {
308-
self.runners.iter().map(|entries| *entries.key()).collect()
309-
}
310-
311270
/// Returns the gateway intents used for this gateway connection.
312271
#[must_use]
313272
pub fn intents(&self) -> GatewayIntents {

0 commit comments

Comments
 (0)