use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use jaeb::{EventBus, EventHandler, HandlerResult, SyncEventHandler};
#[derive(Clone, Debug)]
struct Boom;
#[derive(Clone, Debug)]
struct Safe;
struct PanicHandler;
impl SyncEventHandler<Boom> for PanicHandler {
fn handle(&self, _event: &Boom) -> HandlerResult {
panic!("handler panicked on purpose");
}
}
struct AsyncPanicHandler;
impl EventHandler<Boom> for AsyncPanicHandler {
async fn handle(&self, _event: &Boom) -> HandlerResult {
panic!("async handler panicked on purpose");
}
}
struct SafeCounter {
count: Arc<AtomicUsize>,
}
impl SyncEventHandler<Safe> for SafeCounter {
fn handle(&self, event: &Safe) -> HandlerResult {
let _ = event;
self.count.fetch_add(1, Ordering::SeqCst);
Ok(())
}
}
#[tokio::test]
async fn panicking_handler_does_not_crash_bus() {
let bus = EventBus::new(16).expect("valid config");
let count = Arc::new(AtomicUsize::new(0));
let _ = bus.subscribe(PanicHandler).await.expect("subscribe panic handler");
let _ = bus
.subscribe(SafeCounter { count: Arc::clone(&count) })
.await
.expect("subscribe safe handler");
bus.publish(Boom).await.expect("publish Boom");
bus.publish(Safe).await.expect("publish Safe after panic");
assert_eq!(count.load(Ordering::SeqCst), 1);
bus.shutdown().await.expect("shutdown");
}
#[tokio::test]
async fn async_panicking_handler_does_not_crash_bus() {
let bus = EventBus::new(16).expect("valid config");
let count = Arc::new(AtomicUsize::new(0));
let _ = bus.subscribe(AsyncPanicHandler).await.expect("subscribe async panic handler");
let _ = bus
.subscribe(SafeCounter { count: Arc::clone(&count) })
.await
.expect("subscribe safe handler");
bus.publish(Boom).await.expect("publish Boom");
bus.publish(Safe).await.expect("publish Safe after async panic");
assert_eq!(count.load(Ordering::SeqCst), 1);
bus.shutdown().await.expect("shutdown");
}