use std::sync::Arc; use std::sync::atomic::{AtomicU64, Ordering}; use serde::{Deserialize, Serialize}; use tokio::sync::broadcast; use uuid::Uuid; use crate::models::base_info::UserBaseInfo; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum ChannelAction { Created, Updated, Deleted, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ChannelEvent { pub channel_id: Uuid, pub action: ChannelAction, pub workspace_name: Option, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum MemberAction { Joined, Updated, Kicked, Left, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MemberEvent { pub channel_id: Uuid, pub user: UserBaseInfo, pub user_id: Uuid, pub action: MemberAction, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum CategoryAction { Created, Updated, Deleted, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CategoryEvent { pub workspace_name: String, pub category_id: Uuid, pub action: CategoryAction, } #[derive(Debug, Clone)] pub enum ImEvent { Channel { request_id: Uuid, data: ChannelEvent, }, Member { request_id: Uuid, data: MemberEvent, }, Category { request_id: Uuid, data: CategoryEvent, }, } #[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) } }