Docs: Warn about twilight task deadlock

Potential deadlock (identified by a user) has now been warned about. The way the example is structured prevents this from occurring, but it's worth making this more explicit due to the more free-form nature of twilight.

The design of serenity's event handling and framework should prevent this issue from cropping up when using it as a gateway backend.
This commit is contained in:
Kyle Simpson
2020-12-27 00:16:05 +00:00
parent 504b8dfaef
commit c0d3cb3113

View File

@@ -182,8 +182,11 @@ impl Songbird {
/// If you _only_ need to retrieve the handler for a target, then use /// If you _only_ need to retrieve the handler for a target, then use
/// [`get`]. /// [`get`].
/// ///
/// Twilight users should read the caveats mentioned in [`process`].
///
/// [`Call`]: Call /// [`Call`]: Call
/// [`get`]: Songbird::get /// [`get`]: Songbird::get
/// [`process`]: #method.process
#[inline] #[inline]
pub async fn join<C, G>(&self, guild_id: G, channel_id: C) -> (Arc<Mutex<Call>>, JoinResult<()>) pub async fn join<C, G>(&self, guild_id: G, channel_id: C) -> (Arc<Mutex<Call>>, JoinResult<()>)
where where
@@ -310,6 +313,17 @@ impl Songbird {
/// ///
/// When using twilight, you are required to call this with all inbound /// When using twilight, you are required to call this with all inbound
/// (voice) events, *i.e.*, at least `VoiceStateUpdate`s and `VoiceServerUpdate`s. /// (voice) events, *i.e.*, at least `VoiceStateUpdate`s and `VoiceServerUpdate`s.
///
/// Users *must* ensure that calls to this function happen on a **separate task**
/// to any calls to [`join`], [`join_gateway`]. The simplest way to ensure this is
/// to `tokio::spawn` any command invocation.
///
/// Returned futures generally require the inner [`Call`] to be updated via this function,
/// and will deadlock if event processing is not carried out on another spawned task.
///
/// [`join`]: Songbird::join
/// [`join_gateway`]: Songbird::join_gateway
/// [`Call`]: Call
pub async fn process(&self, event: &TwilightEvent) { pub async fn process(&self, event: &TwilightEvent) {
match event { match event {
TwilightEvent::VoiceServerUpdate(v) => { TwilightEvent::VoiceServerUpdate(v) => {