From 7ae389f3b165a7b4f9b17ef96545f5430cfcd7bc Mon Sep 17 00:00:00 2001 From: metamuffin Date: Wed, 19 Mar 2025 00:22:01 +0100 Subject: delay module --- src/modules/delay.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/modules/fallback.rs | 1 + src/modules/mod.rs | 4 +++- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/modules/delay.rs (limited to 'src') diff --git a/src/modules/delay.rs b/src/modules/delay.rs new file mode 100644 index 0000000..ab46a90 --- /dev/null +++ b/src/modules/delay.rs @@ -0,0 +1,47 @@ +use super::{Node, NodeContext, NodeKind, NodeRequest, NodeResponse}; +use crate::{config::DynNode, error::ServiceError}; +use anyhow::Result; +use rand_distr::Distribution; +use serde::Deserialize; +use serde_yml::Value; +use std::{future::Future, pin::Pin, sync::Arc, time::Duration}; +use tokio::time::sleep; + +pub struct DelayKind; + +#[derive(Deserialize)] +struct Delay { + duration: u64, + stdev: u64, + next: DynNode, +} + +impl NodeKind for DelayKind { + fn name(&self) -> &'static str { + "delay" + } + fn instanciate(&self, config: Value) -> Result> { + Ok(Arc::new(serde_yml::from_value::(config)?)) + } +} +impl Node for Delay { + fn handle<'a>( + &'a self, + context: &'a mut NodeContext, + request: NodeRequest, + ) -> Pin> + Send + Sync + 'a>> { + Box::pin(async move { + sleep(Duration::from_millis(if self.stdev == 0 { + self.duration + } else { + self.duration.saturating_add_signed( + rand_distr::Normal::new(0., self.stdev as f32) + .unwrap() + .sample(&mut rand::rng()) as i64, + ) + })) + .await; + self.next.handle(context, request).await + }) + } +} diff --git a/src/modules/fallback.rs b/src/modules/fallback.rs index 6a5caaa..22ae1ef 100644 --- a/src/modules/fallback.rs +++ b/src/modules/fallback.rs @@ -20,6 +20,7 @@ impl NodeKind for FallbackKind { Ok(Arc::new(serde_yml::from_value::(config)?)) } } + impl Node for Fallback { fn handle<'a>( &'a self, diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 283c86a..c9a7708 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -12,6 +12,7 @@ mod auth; mod cache; mod cgi; mod debug; +mod delay; mod error; mod fallback; mod file; @@ -19,13 +20,13 @@ mod files; mod headers; mod hosts; mod inspect; +mod limits; mod loadbalance; mod paths; mod proxy; mod redirect; mod switch; mod upgrade_insecure; -mod limits; pub type NodeRequest = Request>; pub type NodeResponse = Response>; @@ -52,6 +53,7 @@ pub static MODULES: &[&dyn NodeKind] = &[ &inspect::InspectKind, &fallback::FallbackKind, &limits::LimitsKind, + &delay::DelayKind, ]; pub struct NodeContext { -- cgit v1.2.3-70-g09d2