Wrap event execution in tokio::spawn to avoid deadlocks

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

2
Cargo.lock generated

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

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

@ -43,21 +43,26 @@ impl<T> EventCallback<T> {
/// // ...
/// ```
pub struct RichEventHandler {
callbacks: HashMap<TypeId, Vec<Box<dyn Any + Send + Sync>>>,
callbacks: HashMap<TypeId, Vec<Arc<dyn Any + Send + Sync>>>,
}
impl RichEventHandler {
/// Handles a generic event
async fn handle_event<T: 'static>(&self, ctx: &Context, value: T) {
if let Some(callbacks) = self.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);
async fn handle_event<T: 'static + Send + Sync>(&self, ctx: Context, value: T) {
let callbacks = self.callbacks.clone();
tokio::spawn(async move {
let value = value;
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
@ -76,7 +81,7 @@ impl RichEventHandler {
self.callbacks.insert(type_id, Vec::new());
self.callbacks.get_mut(&type_id).unwrap()
};
callbacks.push(Box::new(EventCallback {
callbacks.push(Arc::new(EventCallback {
inner: Arc::new(cb),
}));
@ -122,44 +127,44 @@ impl Default for RichEventHandler {
impl RawEventHandler for RichEventHandler {
async fn raw_event(&self, ctx: Context, event: Event) {
match event {
Event::ChannelCreate(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::ChannelUpdate(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::GuildCreate(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::GuildIntegrationsUpdate(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::GuildMemberUpdate(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::GuildRoleDelete(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::GuildUpdate(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::MessageCreate(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::MessageUpdate(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::ReactionAdd(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::Ready(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::UserUpdate(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::WebhookUpdate(e) => self.handle_event(&ctx, e).await,
Event::Unknown(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::ChannelPinsUpdate(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::GuildBanRemove(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::GuildEmojisUpdate(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::GuildMemberRemove(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::GuildRoleCreate(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::GuildUnavailable(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::InviteDelete(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::MessageDeleteBulk(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::PresencesReplace(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::ReactionRemoveAll(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::TypingStart(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::VoiceServerUpdate(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,
_ => {}
}
}

Loading…
Cancel
Save