web3-proxy/latency/src/ewma.rs

78 lines
1.7 KiB
Rust
Raw Normal View History

2023-06-18 19:47:40 +03:00
use crate::util::span::span_to_alpha;
use serde::ser::Serializer;
use serde::Serialize;
use tokio::time::Duration;
2023-06-18 19:47:40 +03:00
use watermill::ewmean::EWMean;
use watermill::stats::Univariate;
pub struct EwmaLatency {
/// exponentially weighted of some latency in milliseconds
2023-06-18 19:47:40 +03:00
/// TODO: compare crates: ewma vs watermill
seconds: EWMean<f32>,
}
2023-06-18 19:47:40 +03:00
/// serialize as milliseconds
impl Serialize for EwmaLatency {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
2023-06-18 19:47:40 +03:00
serializer.serialize_f32(self.seconds.get() * 1000.0)
}
}
impl EwmaLatency {
#[inline]
pub fn record(&mut self, duration: Duration) {
2023-06-18 19:47:40 +03:00
self.record_secs(duration.as_secs_f32());
}
#[inline]
2023-06-18 19:47:40 +03:00
pub fn record_secs(&mut self, secs: f32) {
self.seconds.update(secs);
}
2023-06-18 19:47:40 +03:00
/// Current EWMA value in seconds
#[inline]
2023-06-18 19:47:40 +03:00
pub fn value(&self) -> f32 {
self.seconds.get()
}
/// Current EWMA value in seconds
#[inline]
pub fn duration(&self) -> Duration {
let x = self.seconds.get();
Duration::from_secs_f32(x)
}
}
impl Default for EwmaLatency {
fn default() -> Self {
// TODO: what should the default span be? 10 requests?
let span = 10.0;
// TODO: what should the defautt start be?
let start = 1.0;
Self::new(span, start)
}
}
impl EwmaLatency {
// depending on the span, start might not be perfect
2023-06-18 19:47:40 +03:00
pub fn new(span: f32, start_ms: f32) -> Self {
let alpha = span_to_alpha(span);
2023-06-18 19:47:40 +03:00
let mut seconds = EWMean::new(alpha);
if start_ms > 0.0 {
for _ in 0..(span as u64) {
2023-06-18 19:47:40 +03:00
seconds.update(start_ms);
}
}
2023-06-18 19:47:40 +03:00
Self { seconds }
}
}