diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/modules/delay.rs | 47 | ||||
-rw-r--r-- | src/modules/fallback.rs | 1 | ||||
-rw-r--r-- | src/modules/mod.rs | 4 |
3 files changed, 51 insertions, 1 deletions
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<Arc<dyn Node>> { + Ok(Arc::new(serde_yml::from_value::<Delay>(config)?)) + } +} +impl Node for Delay { + fn handle<'a>( + &'a self, + context: &'a mut NodeContext, + request: NodeRequest, + ) -> Pin<Box<dyn Future<Output = Result<NodeResponse, ServiceError>> + 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::<Fallback>(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<BoxBody<Bytes, ServiceError>>; pub type NodeResponse = Response<BoxBody<Bytes, ServiceError>>; @@ -52,6 +53,7 @@ pub static MODULES: &[&dyn NodeKind] = &[ &inspect::InspectKind, &fallback::FallbackKind, &limits::LimitsKind, + &delay::DelayKind, ]; pub struct NodeContext { |