Wrap event execution in tokio::spawn to avoid deadlocks

Signed-off-by: trivernis <trivernis@protonmail.com>
main
trivernis 3 years ago
parent d7c84a2d26
commit 7eb362e8bc
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

2
Cargo.lock generated

@ -1033,7 +1033,7 @@ dependencies = [
[[package]] [[package]]
name = "serenity-rich-interaction" name = "serenity-rich-interaction"
version = "0.2.0" version = "0.2.1"
dependencies = [ dependencies = [
"futures", "futures",
"log", "log",

@ -1,6 +1,6 @@
[package] [package]
name = "serenity-rich-interaction" name = "serenity-rich-interaction"
version = "0.2.0" version = "0.2.1"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
description = "Menus and self deleting messages for the serenity discord framework" description = "Menus and self deleting messages for the serenity discord framework"

@ -43,21 +43,26 @@ impl<T> EventCallback<T> {
/// // ... /// // ...
/// ``` /// ```
pub struct RichEventHandler { pub struct RichEventHandler {
callbacks: HashMap<TypeId, Vec<Box<dyn Any + Send + Sync>>>, callbacks: HashMap<TypeId, Vec<Arc<dyn Any + Send + Sync>>>,
} }
impl RichEventHandler { impl RichEventHandler {
/// Handles a generic event /// Handles a generic event
async fn handle_event<T: 'static>(&self, ctx: &Context, value: T) { async fn handle_event<T: 'static + Send + Sync>(&self, ctx: Context, value: T) {
if let Some(callbacks) = self.callbacks.get(&TypeId::of::<T>()) { let callbacks = self.callbacks.clone();
for callback in callbacks {
if let Some(cb) = callback.downcast_ref::<EventCallback<T>>() { tokio::spawn(async move {
if let Err(e) = cb.run(ctx, &value).await { let value = value;
log::error!("Error in event callback: {:?}", e); if let Some(callbacks) = callbacks.get(&TypeId::of::<T>()) {
for callback in callbacks {
if let Some(cb) = callback.downcast_ref::<EventCallback<T>>() {
if let Err(e) = cb.run(&ctx, &value).await {
log::error!("Error in event callback: {:?}", e);
}
} }
} }
} }
} });
} }
pub fn add_event<T: 'static, F: 'static>(&mut self, cb: F) -> &mut Self pub fn add_event<T: 'static, F: 'static>(&mut self, cb: F) -> &mut Self
@ -76,7 +81,7 @@ impl RichEventHandler {
self.callbacks.insert(type_id, Vec::new()); self.callbacks.insert(type_id, Vec::new());
self.callbacks.get_mut(&type_id).unwrap() self.callbacks.get_mut(&type_id).unwrap()
}; };
callbacks.push(Box::new(EventCallback { callbacks.push(Arc::new(EventCallback {
inner: Arc::new(cb), inner: Arc::new(cb),
})); }));
@ -122,44 +127,44 @@ impl Default for RichEventHandler {
impl RawEventHandler for RichEventHandler { impl RawEventHandler for RichEventHandler {
async fn raw_event(&self, ctx: Context, event: Event) { async fn raw_event(&self, ctx: Context, event: Event) {
match event { match event {
Event::ChannelCreate(e) => self.handle_event(&ctx, e).await, Event::ChannelCreate(e) => self.handle_event(ctx, e).await,
Event::ChannelDelete(e) => self.handle_event(&ctx, e).await, Event::ChannelDelete(e) => self.handle_event(ctx, e).await,
Event::ChannelPinsUpdate(e) => self.handle_event(&ctx, e).await, Event::ChannelPinsUpdate(e) => self.handle_event(ctx, e).await,
Event::ChannelUpdate(e) => self.handle_event(&ctx, e).await, Event::ChannelUpdate(e) => self.handle_event(ctx, e).await,
Event::GuildBanAdd(e) => self.handle_event(&ctx, e).await, Event::GuildBanAdd(e) => self.handle_event(ctx, e).await,
Event::GuildBanRemove(e) => self.handle_event(&ctx, e).await, Event::GuildBanRemove(e) => self.handle_event(ctx, e).await,
Event::GuildCreate(e) => self.handle_event(&ctx, e).await, Event::GuildCreate(e) => self.handle_event(ctx, e).await,
Event::GuildDelete(e) => self.handle_event(&ctx, e).await, Event::GuildDelete(e) => self.handle_event(ctx, e).await,
Event::GuildEmojisUpdate(e) => self.handle_event(&ctx, e).await, Event::GuildEmojisUpdate(e) => self.handle_event(ctx, e).await,
Event::GuildIntegrationsUpdate(e) => self.handle_event(&ctx, e).await, Event::GuildIntegrationsUpdate(e) => self.handle_event(ctx, e).await,
Event::GuildMemberAdd(e) => self.handle_event(&ctx, e).await, Event::GuildMemberAdd(e) => self.handle_event(ctx, e).await,
Event::GuildMemberRemove(e) => self.handle_event(&ctx, e).await, Event::GuildMemberRemove(e) => self.handle_event(ctx, e).await,
Event::GuildMemberUpdate(e) => self.handle_event(&ctx, e).await, Event::GuildMemberUpdate(e) => self.handle_event(ctx, e).await,
Event::GuildMembersChunk(e) => self.handle_event(&ctx, e).await, Event::GuildMembersChunk(e) => self.handle_event(ctx, e).await,
Event::GuildRoleCreate(e) => self.handle_event(&ctx, e).await, Event::GuildRoleCreate(e) => self.handle_event(ctx, e).await,
Event::GuildRoleDelete(e) => self.handle_event(&ctx, e).await, Event::GuildRoleDelete(e) => self.handle_event(ctx, e).await,
Event::GuildRoleUpdate(e) => self.handle_event(&ctx, e).await, Event::GuildRoleUpdate(e) => self.handle_event(ctx, e).await,
Event::GuildUnavailable(e) => self.handle_event(&ctx, e).await, Event::GuildUnavailable(e) => self.handle_event(ctx, e).await,
Event::GuildUpdate(e) => self.handle_event(&ctx, e).await, Event::GuildUpdate(e) => self.handle_event(ctx, e).await,
Event::InviteCreate(e) => self.handle_event(&ctx, e).await, Event::InviteCreate(e) => self.handle_event(ctx, e).await,
Event::InviteDelete(e) => self.handle_event(&ctx, e).await, Event::InviteDelete(e) => self.handle_event(ctx, e).await,
Event::MessageCreate(e) => self.handle_event(&ctx, e).await, Event::MessageCreate(e) => self.handle_event(ctx, e).await,
Event::MessageDelete(e) => self.handle_event(&ctx, e).await, Event::MessageDelete(e) => self.handle_event(ctx, e).await,
Event::MessageDeleteBulk(e) => self.handle_event(&ctx, e).await, Event::MessageDeleteBulk(e) => self.handle_event(ctx, e).await,
Event::MessageUpdate(e) => self.handle_event(&ctx, e).await, Event::MessageUpdate(e) => self.handle_event(ctx, e).await,
Event::PresenceUpdate(e) => self.handle_event(&ctx, e).await, Event::PresenceUpdate(e) => self.handle_event(ctx, e).await,
Event::PresencesReplace(e) => self.handle_event(&ctx, e).await, Event::PresencesReplace(e) => self.handle_event(ctx, e).await,
Event::ReactionAdd(e) => self.handle_event(&ctx, e).await, Event::ReactionAdd(e) => self.handle_event(ctx, e).await,
Event::ReactionRemove(e) => self.handle_event(&ctx, e).await, Event::ReactionRemove(e) => self.handle_event(ctx, e).await,
Event::ReactionRemoveAll(e) => self.handle_event(&ctx, e).await, Event::ReactionRemoveAll(e) => self.handle_event(ctx, e).await,
Event::Ready(e) => self.handle_event(&ctx, e).await, Event::Ready(e) => self.handle_event(ctx, e).await,
Event::Resumed(e) => self.handle_event(&ctx, e).await, Event::Resumed(e) => self.handle_event(ctx, e).await,
Event::TypingStart(e) => self.handle_event(&ctx, e).await, Event::TypingStart(e) => self.handle_event(ctx, e).await,
Event::UserUpdate(e) => self.handle_event(&ctx, e).await, Event::UserUpdate(e) => self.handle_event(ctx, e).await,
Event::VoiceStateUpdate(e) => self.handle_event(&ctx, e).await, Event::VoiceStateUpdate(e) => self.handle_event(ctx, e).await,
Event::VoiceServerUpdate(e) => self.handle_event(&ctx, e).await, Event::VoiceServerUpdate(e) => self.handle_event(ctx, e).await,
Event::WebhookUpdate(e) => self.handle_event(&ctx, e).await, Event::WebhookUpdate(e) => self.handle_event(ctx, e).await,
Event::Unknown(e) => self.handle_event(&ctx, e).await, Event::Unknown(e) => self.handle_event(ctx, e).await,
_ => {} _ => {}
} }
} }

Loading…
Cancel
Save