use super::{ThrottleMode, ThrottledIo};
use crate::client::{ConnectionError, ConnectorService, EstablishedClientConnection};
use rama_core::{Layer, Service, io::Io};
use rama_utils::macros::define_inner_service_accessors;
#[derive(Debug, Clone)]
pub struct OutgoingThrottleService<S> {
inner: S,
config: super::ThrottleConfig,
}
impl<S> OutgoingThrottleService<S> {
define_inner_service_accessors!();
}
impl<S, Input> Service<Input> for OutgoingThrottleService<S>
where
S: ConnectorService<Input, Connection: Io + Unpin>,
Input: Send + 'static,
{
type Output = EstablishedClientConnection<ThrottledIo<S::Connection>, Input>;
type Error = ConnectionError;
async fn serve(&self, input: Input) -> Result<Self::Output, Self::Error> {
let EstablishedClientConnection { input, conn } = self.inner.connect(input).await?;
let conn = self.config.wrap(conn);
Ok(EstablishedClientConnection { input, conn })
}
}
#[derive(Debug, Clone, Default)]
pub struct OutgoingThrottleLayer {
config: super::ThrottleConfig,
}
impl OutgoingThrottleLayer {
#[must_use]
pub fn symmetric(mode: ThrottleMode) -> Self {
Self {
config: super::ThrottleConfig {
read: Some(mode.clone()),
write: Some(mode),
quantum: None,
},
}
}
#[must_use]
pub fn read_only(mode: ThrottleMode) -> Self {
Self {
config: super::ThrottleConfig {
read: Some(mode),
write: None,
quantum: None,
},
}
}
#[must_use]
pub fn write_only(mode: ThrottleMode) -> Self {
Self {
config: super::ThrottleConfig {
read: None,
write: Some(mode),
quantum: None,
},
}
}
#[must_use]
pub fn new(read: Option<ThrottleMode>, write: Option<ThrottleMode>) -> Self {
Self {
config: super::ThrottleConfig {
read,
write,
quantum: None,
},
}
}
rama_utils::macros::generate_set_and_with! {
pub fn quantum(mut self, quantum: Option<u64>) -> Self {
self.config.quantum = quantum;
self
}
}
}
impl<S> Layer<S> for OutgoingThrottleLayer {
type Service = OutgoingThrottleService<S>;
fn layer(&self, inner: S) -> Self::Service {
OutgoingThrottleService {
inner,
config: self.config.clone(),
}
}
}