use std::time::SystemTime;
use tokio::sync::broadcast::{self, error::RecvError, error::TryRecvError};
use tokio::time::Instant;
use crate::format::RawRow;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Via {
First,
Notification,
Poll,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Sample {
pub values: Result<Vec<RawRow>, String>,
pub via: Via,
pub at: Instant,
pub time: SystemTime,
}
impl Sample {
pub(super) fn new(values: Result<Vec<RawRow>, String>, via: Via) -> Self {
Self::at(values, via, Instant::now(), SystemTime::now())
}
pub(super) fn at(
values: Result<Vec<RawRow>, String>,
via: Via,
at: Instant,
time: SystemTime,
) -> Self {
Self {
values,
via,
at,
time,
}
}
}
#[derive(Debug)]
pub struct Samples {
receiver: broadcast::Receiver<Sample>,
dropped: u64,
}
impl Samples {
pub(super) fn new(receiver: broadcast::Receiver<Sample>) -> Self {
Self {
receiver,
dropped: 0,
}
}
pub fn try_next(&mut self) -> Option<Sample> {
loop {
match self.receiver.try_recv() {
Ok(sample) => return Some(sample),
Err(TryRecvError::Lagged(missed)) => self.dropped += missed,
Err(TryRecvError::Empty | TryRecvError::Closed) => return None,
}
}
}
pub async fn next(&mut self) -> Option<Sample> {
loop {
match self.receiver.recv().await {
Ok(sample) => return Some(sample),
Err(RecvError::Lagged(missed)) => self.dropped += missed,
Err(RecvError::Closed) => return None,
}
}
}
pub fn dropped(&self) -> u64 {
self.dropped
}
}