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 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/modules/delay.rs (limited to 'src/modules/delay.rs') 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 + }) + } +} -- cgit v1.2.3-70-g09d2