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 }) } }