use std::time::Duration;
use tower::Layer;
use super::service::{Delay, DelayWith, JitterDelay, JitterDelayWith};
#[derive(Clone, Debug)]
pub struct DelayLayer {
delay: Duration,
}
#[derive(Clone, Debug)]
pub struct DelayLayerWith<P> {
delay: Duration,
predicate: P,
}
#[derive(Clone, Debug)]
pub struct JitterDelayLayer {
base: Duration,
pct: f64,
}
#[derive(Clone, Debug)]
pub struct JitterDelayLayerWith<P> {
base: Duration,
pct: f64,
predicate: P,
}
impl DelayLayer {
#[inline]
pub const fn new(delay: Duration) -> Self {
DelayLayer { delay }
}
pub fn when<P, Req>(self, predicate: P) -> DelayLayerWith<P>
where
P: Fn(&Req) -> bool + Clone,
{
DelayLayerWith::new(self.delay, predicate)
}
}
impl<S> Layer<S> for DelayLayer {
type Service = Delay<S>;
#[inline]
fn layer(&self, service: S) -> Self::Service {
Delay::new(service, self.delay)
}
}
impl<P> DelayLayerWith<P> {
#[inline]
pub fn new(delay: Duration, predicate: P) -> Self {
Self { delay, predicate }
}
}
impl<P, S> Layer<S> for DelayLayerWith<P>
where
P: Clone,
{
type Service = DelayWith<S, P>;
#[inline]
fn layer(&self, inner: S) -> Self::Service {
DelayWith::new(inner, self.delay, self.predicate.clone())
}
}
impl JitterDelayLayer {
#[inline]
pub fn new(base: Duration, pct: f64) -> Self {
Self {
base,
pct: pct.clamp(0.0, 1.0),
}
}
pub fn when<P, Req>(self, predicate: P) -> JitterDelayLayerWith<P>
where
P: Fn(&Req) -> bool + Clone,
{
JitterDelayLayerWith::new(self.base, self.pct, predicate)
}
}
impl<S> Layer<S> for JitterDelayLayer {
type Service = JitterDelay<S>;
#[inline]
fn layer(&self, inner: S) -> Self::Service {
JitterDelay::new(inner, self.base, self.pct)
}
}
impl<P> JitterDelayLayerWith<P> {
#[inline]
pub fn new(base: Duration, pct: f64, predicate: P) -> Self {
Self {
base,
pct: pct.clamp(0.0, 1.0),
predicate,
}
}
}
impl<P, S> Layer<S> for JitterDelayLayerWith<P>
where
P: Clone,
{
type Service = JitterDelayWith<S, P>;
#[inline]
fn layer(&self, inner: S) -> Self::Service {
JitterDelayWith::new(inner, self.base, self.pct, self.predicate.clone())
}
}