#![allow(async_fn_in_trait)]
#![deny(missing_docs, missing_debug_implementations)]
#![doc = include_str!("flowchart.mmd")]
pub mod balance;
pub mod buffer;
#[cfg(feature = "compat")]
pub mod compat;
pub mod concurrency_limit;
pub mod depressurize;
pub mod either;
pub mod leak;
pub mod load;
pub mod load_shed;
pub mod map;
pub mod rate_limit;
pub mod retry;
pub mod select;
pub mod service_fn;
pub mod steer;
pub mod then;
use std::{convert::Infallible, sync::Arc, time::Duration};
use buffer::Buffer;
use concurrency_limit::ConcurrencyLimit;
use depressurize::Depressurize;
use either::Either;
use leak::Leak;
use load::{Load, PendingRequests};
use load_shed::LoadShed;
use map::Map;
use rate_limit::RateLimit;
use retry::Retry;
use then::Then;
use tokio::sync::{Mutex, RwLock};
#[cfg(feature = "compat")]
#[doc(inline)]
pub use compat::compat;
#[doc(inline)]
pub use select::select;
#[doc(inline)]
pub use service_fn::service_fn;
#[doc(inline)]
pub use steer::steer;
pub trait Service<Request> {
type Response;
type Permit<'a>
where
Self: 'a;
async fn acquire(&self) -> Self::Permit<'_>;
async fn call<'a>(permit: Self::Permit<'a>, request: Request) -> Self::Response
where
Self: 'a;
}
pub trait ServiceExt<Request>: Service<Request> {
async fn oneshot(&self, request: Request) -> Self::Response
where
Self: Sized,
{
let permit = self.acquire().await;
Self::call(permit, request).await
}
fn then<F>(self, closure: F) -> Then<Self, F>
where
Self: Sized,
{
Then::new(self, closure)
}
fn map<F>(self, closure: F) -> Map<Self, F>
where
Self: Sized,
{
Map::new(self, closure)
}
fn concurrency_limit(self, n_permits: usize) -> ConcurrencyLimit<Self>
where
Self: Sized,
{
ConcurrencyLimit::new(self, n_permits)
}
fn load_shed(self) -> LoadShed<Self>
where
Self: Sized,
{
LoadShed::new(self)
}
fn buffer(self, capacity: usize) -> Buffer<Self>
where
Self: Sized,
{
Buffer::new(self, capacity)
}
fn rate_limit(self, interval: Duration, permits: usize) -> RateLimit<Self>
where
Self: Sized,
{
RateLimit::new(self, interval, permits)
}
fn retry<P>(self, policy: P) -> Retry<Self, P>
where
Self: Sized,
{
Retry::new(self, policy)
}
fn depressurize(self) -> Depressurize<Self>
where
Self: Sized,
{
Depressurize::new(self)
}
fn pending_requests(self) -> PendingRequests<Self>
where
Self: Sized,
{
PendingRequests::new(self)
}
fn leak<'t>(self: Arc<Self>) -> Leak<'t, Self>
where
Self: Sized,
{
Leak::new(self)
}
fn left<T>(self) -> Either<Self, T>
where
Self: Sized,
{
Either::Left(self)
}
fn right<T>(self) -> Either<T, Self>
where
Self: Sized,
{
Either::Right(self)
}
}
impl<Request, S> ServiceExt<Request> for S where S: Service<Request> {}
pub trait TryService<Request>: Service<Request, Response = Result<Self::Ok, Self::Error>> {
type Ok;
type Error;
}
impl<Request, Ok, Error, S> TryService<Request> for S
where
S: Service<Request, Response = Result<Ok, Error>>,
{
type Ok = Ok;
type Error = Error;
}
impl<Request, S> Service<Request> for Arc<S>
where
S: Service<Request>,
{
type Response = S::Response;
type Permit<'a> = S::Permit<'a>
where
S: 'a;
async fn acquire(&self) -> Self::Permit<'_> {
S::acquire(self).await
}
async fn call(permit: Self::Permit<'_>, request: Request) -> Self::Response {
S::call(permit, request).await
}
}
impl<S> Load for Arc<S>
where
S: Load,
{
type Metric = S::Metric;
fn load(&self) -> Self::Metric {
S::load(self)
}
}
impl<'t, Request, S> Service<Request> for &'t S
where
S: Service<Request>,
{
type Response = S::Response;
type Permit<'a> = S::Permit<'a>
where
S:'a, 't: 'a;
async fn acquire(&self) -> Self::Permit<'_> {
S::acquire(self).await
}
async fn call<'a>(permit: Self::Permit<'a>, request: Request) -> Self::Response
where
Self: 'a,
{
S::call(permit, request).await
}
}
impl<'t, S> Load for &'t S
where
S: Load,
{
type Metric = S::Metric;
fn load(&self) -> Self::Metric {
S::load(self)
}
}
impl<Request, Permit, S> Service<Request> for Mutex<S>
where
for<'a> S: Service<Request, Permit<'a> = Permit>,
S: 'static,
{
type Response = S::Response;
type Permit<'a> = Permit
where
S: 'a;
async fn acquire(&self) -> Self::Permit<'_> {
let guard = self.lock().await;
guard.acquire().await
}
async fn call(permit: Self::Permit<'_>, request: Request) -> Self::Response {
S::call(permit, request).await
}
}
impl<Request, S, Permit> Service<Request> for RwLock<S>
where
for<'a> S: Service<Request, Permit<'a> = Permit>,
S: 'static,
{
type Response = S::Response;
type Permit<'a> = S::Permit<'a>
where
Self: 'a;
async fn acquire(&self) -> Self::Permit<'_> {
self.read().await.acquire().await
}
async fn call(permit: Self::Permit<'_>, request: Request) -> Self::Response {
S::call(permit, request).await
}
}
pub trait Middleware<S> {
type Service;
fn apply(self, svc: S) -> Self::Service;
}
#[derive(Debug, Clone)]
pub struct MiddlewareBuilder;
impl Service<Infallible> for MiddlewareBuilder {
type Permit<'a> = ();
type Response = Infallible;
async fn acquire(&self) -> Self::Permit<'_> {}
async fn call<'a>(_permit: Self::Permit<'a>, request: Infallible) -> Self::Response
where
Self: 'a,
{
request
}
}
impl<S> Middleware<S> for MiddlewareBuilder {
type Service = S;
fn apply(self, svc: S) -> Self::Service {
svc
}
}