use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{self, Sender};
use std::sync::{Arc, Mutex};
pub struct Hub {
subscribers: Mutex<Vec<Sender<Arc<str>>>>,
count: AtomicUsize,
}
impl Hub {
pub fn new() -> Self {
Self {
subscribers: Mutex::new(Vec::new()),
count: AtomicUsize::new(0),
}
}
#[inline]
pub fn has_subscribers(&self) -> bool {
self.count.load(Ordering::Relaxed) > 0
}
pub fn subscribe(&self) -> mpsc::Receiver<Arc<str>> {
let (tx, rx) = mpsc::channel::<Arc<str>>();
let mut subs = self.subscribers.lock().expect("hub poisoned");
subs.push(tx);
self.count.store(subs.len(), Ordering::Relaxed);
rx
}
pub fn broadcast(&self, line: &str) {
let shared: Arc<str> = Arc::from(line);
let mut subs = self.subscribers.lock().expect("hub poisoned");
subs.retain(|tx| tx.send(shared.clone()).is_ok());
self.count.store(subs.len(), Ordering::Relaxed);
}
}
impl Default for Hub {
fn default() -> Self {
Self::new()
}
}