Gateway: Add connection timeout, add Config to gateway. (#51)
This change fixes tasks hanging due to rare cases of messages being lost between full Discord reconnections by placing a configurable timeout on the `ConnectionInfo` responses. This is a companion fix to [serenity#1255](https://github.com/serenity-rs/serenity/pull/1255). To make this doable, `Config`s are now used by all versions of `Songbird`/`Call`, and relevant functions are added to simplify setup with configuration. These are now non-exhaustive, correcting an earlier oversight. For future extensibility, this PR moves the return type of `join`/`join_gateway` into a custom future (no longer leaking flume's `RecvFut` type). Additionally, this fixes the Makefile's feature sets for driver/gateway-only compilation. This is a breaking change in: * the return types of `join`/`join_gateway` * moving `crate::driver::Config` -> `crate::Config`, * `Config` and `JoinError` becoming `#[non_breaking]`. This was tested via `cargo make ready`, and by testing `examples/serenity/voice_receive` with various timeout settings.
This commit is contained in:
@@ -1,81 +0,0 @@
|
||||
use super::{CryptoMode, DecodeMode};
|
||||
|
||||
/// Configuration for the inner Driver.
|
||||
///
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Config {
|
||||
/// Selected tagging mode for voice packet encryption.
|
||||
///
|
||||
/// Defaults to [`CryptoMode::Normal`].
|
||||
///
|
||||
/// Changes to this field will not immediately apply if the
|
||||
/// driver is actively connected, but will apply to subsequent
|
||||
/// sessions.
|
||||
///
|
||||
/// [`CryptoMode::Normal`]: CryptoMode::Normal
|
||||
pub crypto_mode: CryptoMode,
|
||||
/// Configures whether decoding and decryption occur for all received packets.
|
||||
///
|
||||
/// If voice receiving voice packets, generally you should choose [`DecodeMode::Decode`].
|
||||
/// [`DecodeMode::Decrypt`] is intended for users running their own selective decoding,
|
||||
/// who rely upon [user speaking events], or who need to inspect Opus packets.
|
||||
/// If you're certain you will never need any RT(C)P events, then consider [`DecodeMode::Pass`].
|
||||
///
|
||||
/// Defaults to [`DecodeMode::Decrypt`]. This is due to per-packet decoding costs,
|
||||
/// which most users will not want to pay, but allowing speaking events which are commonly used.
|
||||
///
|
||||
/// [`DecodeMode::Decode`]: DecodeMode::Decode
|
||||
/// [`DecodeMode::Decrypt`]: DecodeMode::Decrypt
|
||||
/// [`DecodeMode::Pass`]: DecodeMode::Pass
|
||||
/// [user speaking events]: crate::events::CoreEvent::SpeakingUpdate
|
||||
pub decode_mode: DecodeMode,
|
||||
/// Number of concurrently active tracks to allocate memory for.
|
||||
///
|
||||
/// This should be set at, or just above, the maximum number of tracks
|
||||
/// you expect your bot will play at the same time. Exceeding the size of
|
||||
/// the internal queue will trigger a larger memory allocation and copy,
|
||||
/// possibly causing the mixer thread to miss a packet deadline.
|
||||
///
|
||||
/// Defaults to `1`.
|
||||
///
|
||||
/// Changes to this field in a running driver will only ever increase
|
||||
/// the capacity of the track store.
|
||||
pub preallocated_tracks: usize,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
crypto_mode: CryptoMode::Normal,
|
||||
decode_mode: DecodeMode::Decrypt,
|
||||
preallocated_tracks: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Sets this `Config`'s chosen cryptographic tagging scheme.
|
||||
pub fn crypto_mode(mut self, crypto_mode: CryptoMode) -> Self {
|
||||
self.crypto_mode = crypto_mode;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets this `Config`'s received packet decryption/decoding behaviour.
|
||||
pub fn decode_mode(mut self, decode_mode: DecodeMode) -> Self {
|
||||
self.decode_mode = decode_mode;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets this `Config`'s number of tracks to preallocate.
|
||||
pub fn preallocated_tracks(mut self, preallocated_tracks: usize) -> Self {
|
||||
self.preallocated_tracks = preallocated_tracks;
|
||||
self
|
||||
}
|
||||
|
||||
/// This is used to prevent changes which would invalidate the current session.
|
||||
pub(crate) fn make_safe(&mut self, previous: &Config, connected: bool) {
|
||||
if connected {
|
||||
self.crypto_mode = previous.crypto_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,11 @@
|
||||
#[cfg(feature = "internals")]
|
||||
pub mod bench_internals;
|
||||
|
||||
mod config;
|
||||
pub(crate) mod connection;
|
||||
mod crypto;
|
||||
mod decode_mode;
|
||||
pub(crate) mod tasks;
|
||||
|
||||
pub use config::Config;
|
||||
use connection::error::{Error, Result};
|
||||
pub use crypto::CryptoMode;
|
||||
pub(crate) use crypto::CryptoState;
|
||||
@@ -29,6 +27,7 @@ use crate::{
|
||||
events::EventData,
|
||||
input::Input,
|
||||
tracks::{self, Track, TrackHandle},
|
||||
Config,
|
||||
ConnectionInfo,
|
||||
Event,
|
||||
EventHandler,
|
||||
@@ -212,13 +211,19 @@ impl Driver {
|
||||
self.send(CoreMessage::SetTrack(None))
|
||||
}
|
||||
|
||||
/// Sets the configuration for this driver.
|
||||
/// Sets the configuration for this driver (and parent `Call`, if applicable).
|
||||
#[instrument(skip(self))]
|
||||
pub fn set_config(&mut self, config: Config) {
|
||||
self.config = config.clone();
|
||||
self.send(CoreMessage::SetConfig(config))
|
||||
}
|
||||
|
||||
/// Returns a view of this driver's configuration.
|
||||
#[instrument(skip(self))]
|
||||
pub fn config(&self) -> &Config {
|
||||
&self.config
|
||||
}
|
||||
|
||||
/// Attach a global event handler to an audio context. Global events may receive
|
||||
/// any [`EventContext`].
|
||||
///
|
||||
|
||||
@@ -17,6 +17,7 @@ pub enum Recipient {
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum Error {
|
||||
Crypto(CryptoError),
|
||||
/// Received an illegal voice packet on the voice UDP socket.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use super::{disposal, error::Result, message::*, Config};
|
||||
use super::{disposal, error::Result, message::*};
|
||||
use crate::{
|
||||
constants::*,
|
||||
tracks::{PlayMode, Track},
|
||||
Config,
|
||||
};
|
||||
use audiopus::{
|
||||
coder::Encoder as OpusEncoder,
|
||||
|
||||
@@ -9,11 +9,8 @@ pub(crate) mod udp_rx;
|
||||
pub(crate) mod udp_tx;
|
||||
pub(crate) mod ws;
|
||||
|
||||
use super::{
|
||||
connection::{error::Error as ConnectionError, Connection},
|
||||
Config,
|
||||
};
|
||||
use crate::events::CoreContext;
|
||||
use super::connection::{error::Error as ConnectionError, Connection};
|
||||
use crate::{events::CoreContext, Config};
|
||||
use flume::{Receiver, RecvError, Sender};
|
||||
use message::*;
|
||||
#[cfg(not(feature = "tokio-02-marker"))]
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
use super::{
|
||||
error::{Error, Result},
|
||||
message::*,
|
||||
Config,
|
||||
};
|
||||
use crate::{
|
||||
constants::*,
|
||||
driver::{Config, DecodeMode},
|
||||
events::CoreContext,
|
||||
};
|
||||
use crate::{constants::*, driver::DecodeMode, events::CoreContext};
|
||||
use audiopus::{
|
||||
coder::Decoder as OpusDecoder,
|
||||
error::{Error as OpusError, ErrorCode},
|
||||
|
||||
Reference in New Issue
Block a user