use super::BalanceMake; use rand::{rngs::SmallRng, Rng, SeedableRng}; use std::{fmt, marker::PhantomData}; use tower_layer::Layer; /// Efficiently distributes requests across an arbitrary number of services #[derive(Clone)] pub struct BalanceLayer { rng: SmallRng, _marker: PhantomData, } impl BalanceLayer { /// Builds a balancer using the system entropy. pub fn new() -> Self { Self { rng: SmallRng::from_entropy(), _marker: PhantomData, } } /// Builds a balancer from the provided RNG. /// /// This may be preferrable when many balancers are initialized. pub fn from_rng(rng: &mut R) -> Result { let rng = SmallRng::from_rng(rng)?; Ok(Self { rng, _marker: PhantomData, }) } } impl Layer for BalanceLayer { type Service = BalanceMake; fn layer(&self, make_discover: S) -> Self::Service { BalanceMake::new(make_discover, self.rng.clone()) } } impl fmt::Debug for BalanceLayer { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("BalanceLayer") .field("rng", &self.rng) .finish() } }