use std::time::Duration;
use tokio::time::Instant;
pub struct NeverRestart;
impl<K> Breaker<K> for NeverRestart {
fn may_restart(&mut self, _key: &K, _at: Instant) -> bool {
false
}
}
pub struct AlwaysRestart;
impl<K> Breaker<K> for AlwaysRestart {
fn may_restart(&mut self, _key: &K, _at: Instant) -> bool {
true
}
}
pub struct RateLimited {
max: usize,
period: Duration,
seen: Vec<Instant>,
}
impl Default for RateLimited {
fn default() -> Self {
Self::new(3, Duration::from_secs(10))
}
}
impl RateLimited {
pub fn new(max: usize, period: Duration) -> Self {
Self { max, period, seen: Vec::new() }
}
}
impl<K> Breaker<K> for RateLimited {
fn may_restart(&mut self, _key: &K, at: Instant) -> bool {
self.seen.retain(|&t| {
let age = at.duration_since(t);
age < self.period
});
self.seen.push(at);
self.seen.len() <= self.max
}
}
pub trait Breaker<K>: Send + 'static {
fn may_restart(&mut self, key: &K, at: Instant) -> bool;
}