summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/modules/delay.rs47
-rw-r--r--src/modules/fallback.rs1
-rw-r--r--src/modules/mod.rs4
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 {