diff --git a/lading/src/generator.rs b/lading/src/generator.rs index 8e4f15f30..156681f65 100644 --- a/lading/src/generator.rs +++ b/lading/src/generator.rs @@ -19,6 +19,7 @@ pub mod file_gen; pub mod file_tree; pub mod grpc; pub mod http; +pub mod idle; pub mod process_tree; pub mod splunk_hec; pub mod tcp; @@ -59,6 +60,9 @@ pub enum Error { /// See [`crate::generator::process_tree::Error`] for details. #[error(transparent)] ProcessTree(#[from] process_tree::Error), + /// See [`crate::generator::idle::Error`] for details. + #[error(transparent)] + Idle(#[from] idle::Error), } #[derive(Debug, Deserialize, PartialEq)] @@ -105,6 +109,8 @@ pub enum Inner { UnixDatagram(unix_datagram::Config), /// See [`crate::generator::process_tree::Config`] for details. ProcessTree(process_tree::Config), + /// See [`crate::generator::idle::Config`] for details. + Idle(idle::Config), } #[derive(Debug)] @@ -133,6 +139,8 @@ pub enum Server { UnixDatagram(unix_datagram::UnixDatagram), /// See [`crate::generator::process_tree::ProcessTree`] for details. ProcessTree(process_tree::ProcessTree), + /// See [`crate::generator::idle::Idle`] for details. + Idle(idle::Idle), } impl Server { @@ -171,6 +179,7 @@ impl Server { Inner::ProcessTree(conf) => { Self::ProcessTree(process_tree::ProcessTree::new(&conf, shutdown)?) } + Inner::Idle(conf) => Self::Idle(idle::Idle::new(&conf, shutdown)?), }; Ok(srv) } @@ -202,6 +211,7 @@ impl Server { Server::UnixStream(inner) => inner.spin().await?, Server::UnixDatagram(inner) => inner.spin().await?, Server::ProcessTree(inner) => inner.spin().await?, + Server::Idle(inner) => inner.spin().await?, }; Ok(()) diff --git a/lading/src/generator/idle.rs b/lading/src/generator/idle.rs new file mode 100644 index 000000000..40b36e681 --- /dev/null +++ b/lading/src/generator/idle.rs @@ -0,0 +1,64 @@ +//! The UDP protocol speaking generator. +//! +//! ## Metrics +//! +//! `bytes_written`: Bytes written successfully +//! `packets_sent`: Packets written successfully +//! `request_failure`: Number of failed writes; each occurrence causes a socket re-bind +//! `connection_failure`: Number of socket bind failures +//! `bytes_per_second`: Configured rate to send data +//! +//! Additional metrics may be emitted by this generator's [throttle]. +//! + +use serde::Deserialize; +use tracing::info; + +use crate::signals::Shutdown; + +#[derive(Debug, Deserialize, PartialEq, Clone, Copy)] +/// Configuration of this generator. +pub struct Config {} + +/// Errors produced by [`Idle`]. +#[derive(thiserror::Error, Debug, Clone, Copy)] +pub enum Error {} + +#[derive(Debug)] +/// The Idle generator. +/// +/// This generator is responsible for doing nothing, except wait to shut down. +pub struct Idle { + shutdown: Shutdown, +} + +impl Idle { + /// Create a new [`Idle`] instance + /// + /// # Errors + /// + /// Creation will not fail. + /// + /// # Panics + /// + /// Function will not panic. + #[allow(clippy::cast_possible_truncation)] + pub fn new(_config: &Config, shutdown: Shutdown) -> Result { + Ok(Self { shutdown }) + } + + /// Run [`Idle`] to completion or until a shutdown signal is received. + /// + /// # Errors + /// + /// Function will return an error when the UDP socket cannot be written to. + /// + /// # Panics + /// + /// Function will panic if underlying byte capacity is not available. + pub async fn spin(mut self) -> Result<(), Error> { + self.shutdown.recv().await; + info!("shutdown signal received"); + Ok(()) + } +}