use std::sync::Arc; use std::sync::atomic::{AtomicU64, Ordering}; use tokio::sync::broadcast; use uuid::Uuid; use crate::immediate::{ ArticleEvent, CategoryEvent, ChannelEvent, DraftEvent, FollowEvent, MemberEvent, MessageEvent, PollEvent, PresenceEvent, ReactionEvent, ThreadEvent, TypingEvent, }; #[derive(Debug, Clone)] pub enum ImEvent { Typing { request_id: Uuid, data: TypingEvent, }, Presence { request_id: Uuid, data: PresenceEvent, }, Message { request_id: Uuid, data: MessageEvent, }, Channel { request_id: Uuid, data: ChannelEvent, }, Thread { request_id: Uuid, data: ThreadEvent, }, Member { request_id: Uuid, data: MemberEvent, }, Reaction { request_id: Uuid, data: ReactionEvent, }, Poll { request_id: Uuid, data: PollEvent, }, Article { request_id: Uuid, data: ArticleEvent, }, Category { request_id: Uuid, data: CategoryEvent, }, Draft { request_id: Uuid, data: DraftEvent, }, Follow { request_id: Uuid, data: FollowEvent, }, } #[derive(Clone)] pub struct ImEventBus { tx: broadcast::Sender, lagged: Arc, } impl ImEventBus { pub fn new(capacity: usize) -> Self { let (tx, _) = broadcast::channel(capacity); Self { tx, lagged: Arc::new(AtomicU64::new(0)), } } pub fn publish(&self, event: ImEvent) -> bool { self.tx.send(event).is_ok() } pub fn subscribe(&self) -> broadcast::Receiver { self.tx.subscribe() } pub fn record_lagged(&self, count: u64) { self.lagged.fetch_add(count, Ordering::Relaxed); } pub fn lagged_total(&self) -> u64 { self.lagged.load(Ordering::Relaxed) } } impl Default for ImEventBus { fn default() -> Self { Self::new(1024) } }