use actix::*; use rand::{self, rngs::ThreadRng, Rng}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; pub type ID = i64; #[derive(Debug, Clone)] pub struct Session { pub addr: Recipient, } #[derive(Message)] #[rtype(result = "ID")] pub struct Connect { pub addr: Recipient, } #[derive(Message)] #[rtype(result = "()")] pub struct Disconnect { pub id: ID, } #[derive(Message, Clone, Debug, Serialize, Deserialize)] #[rtype(result = "()")] pub enum Event { HealthcheckChange { app_id: i32, alive: bool }, } #[derive(Default)] pub struct EventBroker { rng: ThreadRng, sessions: HashMap, } impl Supervised for EventBroker {} impl SystemService for EventBroker {} impl Actor for EventBroker { type Context = Context; fn started(&mut self, _: &mut Self::Context) { tracing::info!("EventBroker - Started"); } fn stopped(&mut self, _: &mut Self::Context) { tracing::error!("EventBroker - Shutdown"); } } impl Handler for EventBroker { type Result = ID; fn handle(&mut self, msg: Connect, _: &mut Context) -> Self::Result { tracing::info!("Session connected"); let id = self.rng.gen::(); self.sessions.insert(id, Session { addr: msg.addr }); id } } impl Handler for EventBroker { type Result = (); fn handle(&mut self, msg: Disconnect, _: &mut Context) { tracing::info!("Session disconnected"); self.sessions.remove(&msg.id); } } impl Handler for EventBroker { type Result = (); fn handle(&mut self, msg: Event, _ctx: &mut Self::Context) -> Self::Result { for (_, ses) in self.sessions.iter() { let _ = ses.addr.do_send(msg.clone()); } } }