use tokio::sync::broadcast::{self, error};
use super::ClusterEvent;
#[derive(Debug, thiserror::Error)]
pub enum SubscriberError {
#[error("event manager closed")]
Closed,
#[error("subscriber lagged by {0} events")]
Lagged(u64),
}
#[derive(Debug, thiserror::Error)]
pub enum TryRecvError {
#[error("no event available")]
Empty,
#[error("event manager closed")]
Closed,
#[error("subscriber lagged by {0} events")]
Lagged(u64),
}
#[derive(Debug)]
pub struct Subscriber {
rx: broadcast::Receiver<ClusterEvent>,
}
impl Subscriber {
pub(super) fn new(rx: broadcast::Receiver<ClusterEvent>) -> Self {
Self { rx }
}
pub async fn recv(&mut self) -> Result<ClusterEvent, SubscriberError> {
match self.rx.recv().await {
Ok(evt) => Ok(evt),
Err(error::RecvError::Closed) => Err(SubscriberError::Closed),
Err(error::RecvError::Lagged(n)) => Err(SubscriberError::Lagged(n)),
}
}
pub fn try_recv(&mut self) -> Result<ClusterEvent, TryRecvError> {
match self.rx.try_recv() {
Ok(evt) => Ok(evt),
Err(error::TryRecvError::Empty) => Err(TryRecvError::Empty),
Err(error::TryRecvError::Closed) => Err(TryRecvError::Closed),
Err(error::TryRecvError::Lagged(n)) => Err(TryRecvError::Lagged(n)),
}
}
}