use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration;
use jaeb::{EventBus, 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 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);
let count = Arc::new(AtomicUsize::new(0));
bus.subscribe(PanicHandler).await.expect("subscribe panic handler");
bus.subscribe(SafeCounter { count: Arc::clone(&count) })
.await
.expect("subscribe safe handler");
bus.publish(Boom).await.expect("publish Boom");
tokio::time::sleep(Duration::from_millis(50)).await;
bus.publish(Safe).await.expect("publish Safe after panic");
assert_eq!(count.load(Ordering::SeqCst), 1);
bus.shutdown().await.expect("shutdown");
}