use std::{
sync::{
Arc,
atomic::{AtomicUsize, Ordering},
mpsc::{Sender, channel},
},
thread::{self, JoinHandle},
};
pub(crate) enum Measurement {
Sent(usize),
Received(usize),
}
#[derive(Clone)]
pub(crate) struct Metrics {
total_sent: Arc<AtomicUsize>,
total_read: Arc<AtomicUsize>,
_h: Arc<JoinHandle<()>>,
}
impl Metrics {
pub(crate) fn new() -> (Self, Sender<Measurement>) {
let total_sent: Arc<AtomicUsize> = AtomicUsize::new(0).into();
let total_read: Arc<AtomicUsize> = AtomicUsize::new(0).into();
let sent = total_sent.clone();
let read = total_read.clone();
let (tx, rx) = channel();
let h = thread::spawn(move || {
for m in rx {
match m {
Measurement::Sent(s) => {
sent.fetch_add(s, Ordering::Relaxed);
}
Measurement::Received(s) => {
read.fetch_add(s, Ordering::Relaxed);
}
}
}
});
(
Self {
total_sent,
total_read,
_h: h.into(),
},
tx,
)
}
pub fn sent(&self) -> usize {
self.total_sent.load(Ordering::Relaxed)
}
pub fn read(&self) -> usize {
self.total_read.load(Ordering::Relaxed)
}
}