use rama_utils::octets::kib_u64;
use rama_utils::rate::{Rate, RateLimiter};
mod io;
#[doc(inline)]
pub use io::ThrottledIo;
mod incoming;
#[doc(inline)]
pub use incoming::{ThrottleLayer, ThrottleService};
mod outgoing;
#[doc(inline)]
pub use outgoing::{OutgoingThrottleLayer, OutgoingThrottleService};
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum ThrottleMode {
PerConn {
rate: Rate,
burst: u64,
},
Shared(RateLimiter),
}
impl ThrottleMode {
#[must_use]
pub const fn per_conn(rate: Rate) -> Self {
Self::PerConn {
rate,
burst: rate.units(),
}
}
#[must_use]
pub const fn per_conn_with_burst(rate: Rate, burst: u64) -> Self {
Self::PerConn { rate, burst }
}
#[must_use]
pub const fn shared(limiter: RateLimiter) -> Self {
Self::Shared(limiter)
}
}
fn default_quantum(rate: Rate) -> u64 {
(rate.units() / 10).clamp(1, kib_u64(16))
}
#[derive(Debug, Clone, Default)]
struct ThrottleConfig {
read: Option<ThrottleMode>,
write: Option<ThrottleMode>,
quantum: Option<u64>,
}
impl ThrottleConfig {
fn wrap<S>(&self, stream: S) -> ThrottledIo<S> {
ThrottledIo::new(stream)
.maybe_with_read_mode(self.read.clone())
.maybe_with_write_mode(self.write.clone())
.maybe_with_quantum(self.quantum)
}
}