Remove bounds of Service from Layer

This commit is contained in:
Carl Lerche 2019-04-11 13:38:45 -07:00 committed by Sean McArthur
parent d8e6d6499b
commit 07baf63048
22 changed files with 78 additions and 261 deletions

View File

@ -1,50 +1,45 @@
use crate::{error::Error, service::Buffer, worker::WorkerExecutor}; use crate::{error::Error, service::Buffer, worker::WorkerExecutor};
use std::marker::PhantomData;
use tokio_executor::DefaultExecutor; use tokio_executor::DefaultExecutor;
use tower_layer::Layer; use tower_layer::Layer;
use tower_service::Service; use tower_service::Service;
/// Buffer requests with a bounded buffer /// Buffer requests with a bounded buffer
pub struct BufferLayer<E = DefaultExecutor> { pub struct BufferLayer<Request, E = DefaultExecutor> {
bound: usize, bound: usize,
executor: E, executor: E,
_p: PhantomData<fn(Request)>,
} }
impl BufferLayer<DefaultExecutor> { impl<Request> BufferLayer<Request, DefaultExecutor> {
pub fn new(bound: usize) -> Self { pub fn new(bound: usize) -> Self {
BufferLayer { BufferLayer {
bound, bound,
executor: DefaultExecutor::current(), executor: DefaultExecutor::current(),
_p: PhantomData,
} }
} }
} }
impl<E> BufferLayer<E> { impl<Request, E: Clone> BufferLayer<Request, E> {
pub fn with_executor<S, Request>(bound: usize, executor: E) -> Self pub fn with_executor(bound: usize, executor: E) -> Self {
where BufferLayer {
S: Service<Request>, bound,
S::Error: Into<Error>, executor,
E: WorkerExecutor<S, Request> + Clone, _p: PhantomData,
{ }
BufferLayer { bound, executor }
} }
} }
impl<E, S, Request> Layer<S, Request> for BufferLayer<E> impl<E, S, Request> Layer<S> for BufferLayer<Request, E>
where where
S: Service<Request>, S: Service<Request>,
S::Error: Into<Error>, S::Error: Into<Error>,
E: WorkerExecutor<S, Request> + Clone, E: WorkerExecutor<S, Request> + Clone,
{ {
type Response = S::Response;
type Error = Error;
type LayerError = Error;
type Service = Buffer<S, Request>; type Service = Buffer<S, Request>;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> { fn layer(&self, service: S) -> Self::Service {
Ok(Buffer::with_executor( Buffer::with_executor(service, self.bound, &mut self.executor.clone())
service,
self.bound,
&mut self.executor.clone(),
))
} }
} }

View File

@ -46,8 +46,3 @@ impl error::Error for Error {
} }
} }
} }
pub(crate) mod never {
#[derive(Debug)]
pub enum Never {}
}

View File

@ -1,9 +1,5 @@
use crate::{ use crate::Filter;
error::{self, Error},
Filter, Predicate,
};
use tower_layer::Layer; use tower_layer::Layer;
use tower_service::Service;
pub struct FilterLayer<U> { pub struct FilterLayer<U> {
predicate: U, predicate: U,
@ -15,19 +11,11 @@ impl<U> FilterLayer<U> {
} }
} }
impl<U, S, Request> Layer<S, Request> for FilterLayer<U> impl<U: Clone, S> Layer<S> for FilterLayer<U> {
where
U: Predicate<Request> + Clone,
S: Service<Request> + Clone,
S::Error: Into<error::Source>,
{
type Response = S::Response;
type Error = Error;
type LayerError = error::never::Never;
type Service = Filter<S, U>; type Service = Filter<S, U>;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> { fn layer(&self, service: S) -> Self::Service {
let predicate = self.predicate.clone(); let predicate = self.predicate.clone();
Ok(Filter::new(service, predicate)) Filter::new(service, predicate)
} }
} }

View File

@ -22,12 +22,7 @@ pub struct Filter<T, U> {
} }
impl<T, U> Filter<T, U> { impl<T, U> Filter<T, U> {
pub fn new<Request>(inner: T, predicate: U) -> Self pub fn new(inner: T, predicate: U) -> Self {
where
T: Service<Request> + Clone,
T::Error: Into<error::Source>,
U: Predicate<Request>,
{
Filter { inner, predicate } Filter { inner, predicate }
} }
} }

View File

@ -8,8 +8,6 @@
//! //!
//! A middleware implements the [`Layer`] and [`Service`] trait. //! A middleware implements the [`Layer`] and [`Service`] trait.
use tower_service::Service;
/// Decorates a `Service`, transforming either the request or the response. /// Decorates a `Service`, transforming either the request or the response.
/// ///
/// Often, many of the pieces needed for writing network applications can be /// Often, many of the pieces needed for writing network applications can be
@ -36,21 +34,14 @@ use tower_service::Service;
/// target: &'static str, /// target: &'static str,
/// } /// }
/// ///
/// impl<S, Request> Layer<S, Request> for LogLayer /// impl<S> Layer<S> for LogLayer {
/// where
/// S: Service<Request>,
/// Request: fmt::Debug,
/// {
/// type Response = S::Response;
/// type Error = S::Error;
/// type LayerError = Void;
/// type Service = LogService<S>; /// type Service = LogService<S>;
/// ///
/// fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> { /// fn layer(&self, service: S) -> Self::Service {
/// Ok(LogService { /// LogService {
/// target: self.target, /// target: self.target,
/// service /// service
/// }) /// }
/// } /// }
/// } /// }
/// ///
@ -84,20 +75,10 @@ use tower_service::Service;
/// The above log implementation is decoupled from the underlying protocol and /// The above log implementation is decoupled from the underlying protocol and
/// is also decoupled from client or server concerns. In other words, the same /// is also decoupled from client or server concerns. In other words, the same
/// log middleware could be used in either a client or a server. /// log middleware could be used in either a client or a server.
pub trait Layer<S, Request> { pub trait Layer<S> {
/// The wrapped service response type
type Response;
/// The wrapped service's error type
type Error;
/// The error produced when calling `layer`
type LayerError;
/// The wrapped service /// The wrapped service
type Service: Service<Request, Response = Self::Response, Error = Self::Error>; type Service;
/// Wrap the given service with the middleware, returning a new service /// Wrap the given service with the middleware, returning a new service
/// that has been decorated with the middleware. /// that has been decorated with the middleware.
fn layer(&self, inner: S) -> Result<Self::Service, Self::LayerError>; fn layer(&self, inner: S) -> Self::Service;
} }

View File

@ -1,6 +1,5 @@
use super::{never::Never, ConcurrencyLimit, Error}; use super::ConcurrencyLimit;
use tower_layer::Layer; use tower_layer::Layer;
use tower_service::Service;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ConcurrencyLimitLayer { pub struct ConcurrencyLimitLayer {
@ -13,17 +12,10 @@ impl ConcurrencyLimitLayer {
} }
} }
impl<S, Request> Layer<S, Request> for ConcurrencyLimitLayer impl<S> Layer<S> for ConcurrencyLimitLayer {
where
S: Service<Request>,
S::Error: Into<Error>,
{
type Response = S::Response;
type Error = Error;
type LayerError = Never;
type Service = ConcurrencyLimit<S>; type Service = ConcurrencyLimit<S>;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> { fn layer(&self, service: S) -> Self::Service {
Ok(ConcurrencyLimit::new(service, self.max)) ConcurrencyLimit::new(service, self.max)
} }
} }

View File

@ -2,7 +2,6 @@
pub mod future; pub mod future;
mod layer; mod layer;
mod never;
mod service; mod service;
pub use self::{layer::ConcurrencyLimitLayer, service::ConcurrencyLimit}; pub use self::{layer::ConcurrencyLimitLayer, service::ConcurrencyLimit};

View File

@ -20,10 +20,7 @@ struct Limit {
impl<T> ConcurrencyLimit<T> { impl<T> ConcurrencyLimit<T> {
/// Create a new rate limiter /// Create a new rate limiter
pub fn new<Request>(inner: T, max: usize) -> Self pub fn new(inner: T, max: usize) -> Self {
where
T: Service<Request>,
{
ConcurrencyLimit { ConcurrencyLimit {
inner, inner,
limit: Limit { limit: Limit {

View File

@ -1,18 +1,3 @@
use std::error; use std::error;
pub(crate) type Error = Box<dyn error::Error + Send + Sync>; pub(crate) type Error = Box<dyn error::Error + Send + Sync>;
pub(crate) mod never {
use std::{error, fmt};
#[derive(Debug)]
pub enum Never {}
impl fmt::Display for Never {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
unreachable!();
}
}
impl error::Error for Never {}
}

View File

@ -1,10 +1,6 @@
use super::{ use super::{Rate, RateLimit};
error::{never::Never, Error},
Rate, RateLimit,
};
use std::time::Duration; use std::time::Duration;
use tower_layer::Layer; use tower_layer::Layer;
use tower_service::Service;
#[derive(Debug)] #[derive(Debug)]
pub struct RateLimitLayer { pub struct RateLimitLayer {
@ -18,17 +14,10 @@ impl RateLimitLayer {
} }
} }
impl<S, Request> Layer<S, Request> for RateLimitLayer impl<S> Layer<S> for RateLimitLayer {
where
S: Service<Request>,
Error: From<S::Error>,
{
type Response = S::Response;
type Error = Error;
type LayerError = Never;
type Service = RateLimit<S>; type Service = RateLimit<S>;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> { fn layer(&self, service: S) -> Self::Service {
Ok(RateLimit::new(service, self.rate)) RateLimit::new(service, self.rate)
} }
} }

View File

@ -21,10 +21,7 @@ enum State {
impl<T> RateLimit<T> { impl<T> RateLimit<T> {
/// Create a new rate limiter /// Create a new rate limiter
pub fn new<Request>(inner: T, rate: Rate) -> Self pub fn new(inner: T, rate: Rate) -> Self {
where
T: Service<Request>,
{
let state = State::Ready { let state = State::Ready {
until: clock::now(), until: clock::now(),
rem: rate.num(), rem: rate.num(),

View File

@ -3,7 +3,6 @@
use std::fmt; use std::fmt;
pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>; pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
pub(crate) use self::never::Never;
/// An error returned by `Overload` when the underlying service /// An error returned by `Overload` when the underlying service
/// is not ready to handle any requests at the time of being /// is not ready to handle any requests at the time of being
@ -31,18 +30,3 @@ impl fmt::Display for Overloaded {
} }
impl std::error::Error for Overloaded {} impl std::error::Error for Overloaded {}
pub(crate) mod never {
use std::{error, fmt};
#[derive(Debug)]
pub enum Never {}
impl fmt::Display for Never {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
match *self {}
}
}
impl error::Error for Never {}
}

View File

@ -1,10 +1,6 @@
use tower_layer::Layer; use tower_layer::Layer;
use tower_service::Service;
use crate::{ use crate::LoadShed;
error::{Error, Never},
LoadShed,
};
/// A `tower-layer` to wrap services in `LoadShed` middleware. /// A `tower-layer` to wrap services in `LoadShed` middleware.
#[derive(Debug)] #[derive(Debug)]
@ -19,17 +15,10 @@ impl LoadShedLayer {
} }
} }
impl<S, Req> Layer<S, Req> for LoadShedLayer impl<S> Layer<S> for LoadShedLayer {
where
S: Service<Req>,
S::Error: Into<Error>,
{
type Response = S::Response;
type Error = Error;
type LayerError = Never;
type Service = LoadShed<S>; type Service = LoadShed<S>;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> { fn layer(&self, service: S) -> Self::Service {
Ok(LoadShed::new(service)) LoadShed::new(service)
} }
} }

View File

@ -1,6 +1,6 @@
#![deny(missing_debug_implementations)] #![deny(missing_debug_implementations)]
#![deny(missing_docs)] #![deny(missing_docs)]
#![deny(warnings)] // #![deny(warnings)]
#![deny(rust_2018_idioms)] #![deny(rust_2018_idioms)]
#![allow(elided_lifetimes_in_paths)] #![allow(elided_lifetimes_in_paths)]
@ -11,9 +11,6 @@ use tower_layer::Layer;
use tower_service::Service; use tower_service::Service;
pub mod budget; pub mod budget;
mod never;
use crate::never::Never;
/// A "retry policy" to classify if a request should be retried. /// A "retry policy" to classify if a request should be retried.
/// ///
@ -127,19 +124,15 @@ impl<P> RetryLayer<P> {
} }
} }
impl<P, S, Request> Layer<S, Request> for RetryLayer<P> impl<P, S> Layer<S> for RetryLayer<P>
where where
S: Service<Request> + Clone, P: Clone,
P: Policy<Request, S::Response, S::Error> + Clone,
{ {
type Response = S::Response;
type Error = S::Error;
type LayerError = Never;
type Service = Retry<P, S>; type Service = Retry<P, S>;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> { fn layer(&self, service: S) -> Self::Service {
let policy = self.policy.clone(); let policy = self.policy.clone();
Ok(Retry::new(policy, service)) Retry::new(policy, service)
} }
} }
@ -147,11 +140,7 @@ where
impl<P, S> Retry<P, S> { impl<P, S> Retry<P, S> {
/// Retry the inner service depending on this [`Policy`][Policy}. /// Retry the inner service depending on this [`Policy`][Policy}.
pub fn new<Request>(policy: P, service: S) -> Self pub fn new(policy: P, service: S) -> Self {
where
P: Policy<Request, S::Response, S::Error> + Clone,
S: Service<Request> + Clone,
{
Retry { policy, service } Retry { policy, service }
} }
} }

View File

@ -1,7 +1,7 @@
use crate::{never::Never, Error, Timeout}; use crate::Timeout;
use std::time::Duration; use std::time::Duration;
use tower_layer::Layer; use tower_layer::Layer;
use tower_service::Service;
/// Applies a timeout to requests via the supplied inner service. /// Applies a timeout to requests via the supplied inner service.
#[derive(Debug)] #[derive(Debug)]
pub struct TimeoutLayer { pub struct TimeoutLayer {
@ -15,17 +15,10 @@ impl TimeoutLayer {
} }
} }
impl<S, Request> Layer<S, Request> for TimeoutLayer impl<S> Layer<S> for TimeoutLayer {
where
S: Service<Request>,
Error: From<S::Error>,
{
type Response = S::Response;
type Error = Error;
type LayerError = Never;
type Service = Timeout<S>; type Service = Timeout<S>;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> { fn layer(&self, service: S) -> Self::Service {
Ok(Timeout::new(service, self.timeout)) Timeout::new(service, self.timeout)
} }
} }

View File

@ -11,7 +11,6 @@
pub mod error; pub mod error;
pub mod future; pub mod future;
mod layer; mod layer;
mod never;
pub use crate::layer::TimeoutLayer; pub use crate::layer::TimeoutLayer;

View File

@ -1,12 +0,0 @@
use std::fmt;
#[derive(Debug)]
/// An error that can never occur.
pub enum Never {}
impl fmt::Display for Never {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
match *self {}
}
}
impl std::error::Error for Never {}

View File

@ -1,6 +1,4 @@
use std::fmt;
use tower_layer::Layer; use tower_layer::Layer;
use tower_service::Service;
/// A no-op middleware. /// A no-op middleware.
/// ///
@ -19,28 +17,10 @@ impl Identity {
} }
/// Decorates a `Service`, transforming either the request or the response. /// Decorates a `Service`, transforming either the request or the response.
impl<S, Request> Layer<S, Request> for Identity impl<S> Layer<S> for Identity {
where
S: Service<Request>,
{
type Response = S::Response;
type Error = S::Error;
type LayerError = Never;
type Service = S; type Service = S;
fn layer(&self, inner: S) -> Result<Self::Service, Self::LayerError> { fn layer(&self, inner: S) -> Self::Service {
Ok(inner) inner
} }
} }
/// An error that can never occur.
#[derive(Debug)]
pub enum Never {}
impl fmt::Display for Never {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
match *self {}
}
}
impl ::std::error::Error for Never {}

View File

@ -1,5 +1,4 @@
use tower_layer::Layer; use tower_layer::Layer;
use tower_service::Service;
/// Two middlewares chained together. /// Two middlewares chained together.
/// ///
@ -10,8 +9,6 @@ pub struct Stack<Inner, Outer> {
outer: Outer, outer: Outer,
} }
type Error = Box<dyn std::error::Error + Send + Sync>;
impl<Inner, Outer> Stack<Inner, Outer> { impl<Inner, Outer> Stack<Inner, Outer> {
/// Create a new `Stack`. /// Create a new `Stack`.
pub fn new(inner: Inner, outer: Outer) -> Self { pub fn new(inner: Inner, outer: Outer) -> Self {
@ -19,22 +16,16 @@ impl<Inner, Outer> Stack<Inner, Outer> {
} }
} }
impl<S, Request, Inner, Outer> Layer<S, Request> for Stack<Inner, Outer> impl<S, Inner, Outer> Layer<S> for Stack<Inner, Outer>
where where
S: Service<Request>, Inner: Layer<S>,
Inner: Layer<S, Request>, Outer: Layer<Inner::Service>,
Inner::LayerError: Into<Error>,
Outer: Layer<Inner::Service, Request>,
Outer::LayerError: Into<Error>,
{ {
type Response = Outer::Response;
type Error = Outer::Error;
type LayerError = Error;
type Service = Outer::Service; type Service = Outer::Service;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> { fn layer(&self, service: S) -> Self::Service {
let inner = self.inner.layer(service).map_err(Into::into)?; let inner = self.inner.layer(service);
self.outer.layer(inner).map_err(Into::into) self.outer.layer(inner)
} }
} }

View File

@ -73,7 +73,7 @@ pub(super) type Error = Box<dyn std::error::Error + Send + Sync>;
/// # T::Error: Into<Box<::std::error::Error + Send + Sync>>, /// # T::Error: Into<Box<::std::error::Error + Send + Sync>>,
/// # { /// # {
/// ServiceBuilder::new() /// ServiceBuilder::new()
/// .buffer(100) /// // .buffer(100)
/// .concurrency_limit(10) /// .concurrency_limit(10)
/// .service(my_service) /// .service(my_service)
/// # ; /// # ;
@ -96,7 +96,7 @@ pub(super) type Error = Box<dyn std::error::Error + Send + Sync>;
/// # { /// # {
/// ServiceBuilder::new() /// ServiceBuilder::new()
/// .concurrency_limit(10) /// .concurrency_limit(10)
/// .buffer(100) /// // .buffer(100)
/// .service(my_service) /// .service(my_service)
/// # ; /// # ;
/// # } /// # }
@ -207,12 +207,12 @@ pub(super) type Error = Box<dyn std::error::Error + Send + Sync>;
/// # } /// # }
/// # } /// # }
/// ServiceBuilder::new() /// ServiceBuilder::new()
/// .buffer(5) /// // .buffer(5)
/// .concurrency_limit(5) /// .concurrency_limit(5)
/// .rate_limit(5, Duration::from_secs(1)) /// .rate_limit(5, Duration::from_secs(1))
/// .service(MyService); /// .service(MyService);
/// ``` /// ```
#[derive(Debug)] #[derive(Clone, Debug)]
pub struct ServiceBuilder<L> { pub struct ServiceBuilder<L> {
layer: L, layer: L,
} }
@ -235,7 +235,7 @@ impl<L> ServiceBuilder<L> {
} }
/// Buffer requests when when the next layer is out of capacity. /// Buffer requests when when the next layer is out of capacity.
pub fn buffer(self, bound: usize) -> ServiceBuilder<Stack<BufferLayer, L>> { pub fn buffer<Request>(self, bound: usize) -> ServiceBuilder<Stack<BufferLayer<Request>, L>> {
self.layer(BufferLayer::new(bound)) self.layer(BufferLayer::new(bound))
} }
@ -291,10 +291,10 @@ impl<L> ServiceBuilder<L> {
} }
/// Wrap the service `S` with the layers. /// Wrap the service `S` with the layers.
pub fn service<S, Request>(self, service: S) -> Result<L::Service, L::LayerError> pub fn service<S, Request>(self, service: S) -> L::Service
where where
L: Layer<S, Request>, L: Layer<S>,
S: Service<Request>, L::Service: Service<Request>,
{ {
self.layer.layer(service) self.layer.layer(service)
} }

View File

@ -1,4 +1,3 @@
use super::Error;
use crate::Service; use crate::Service;
use futures::{try_ready, Async, Future, Poll}; use futures::{try_ready, Async, Future, Poll};
use std::{marker::PhantomData, sync::Arc}; use std::{marker::PhantomData, sync::Arc};
@ -36,17 +35,15 @@ impl<S, L, Request> LayeredMakeService<S, L, Request> {
impl<S, L, Target, Request> Service<Target> for LayeredMakeService<S, L, Request> impl<S, L, Target, Request> Service<Target> for LayeredMakeService<S, L, Request>
where where
S: MakeService<Target, Request>, S: MakeService<Target, Request>,
S::MakeError: Into<Error>, L: Layer<S::Service> + Sync + Send + 'static,
L: Layer<S::Service, Request> + Sync + Send + 'static,
L::LayerError: Into<Error>,
Target: Clone, Target: Clone,
{ {
type Response = L::Service; type Response = L::Service;
type Error = Error; type Error = S::MakeError;
type Future = ServiceFuture<S, L, Target, Request>; type Future = ServiceFuture<S, L, Target, Request>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> { fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.maker.poll_ready().map_err(Into::into) self.maker.poll_ready()
} }
fn call(&mut self, target: Target) -> Self::Future { fn call(&mut self, target: Target) -> Self::Future {
@ -60,19 +57,14 @@ where
impl<S, L, Target, Request> Future for ServiceFuture<S, L, Target, Request> impl<S, L, Target, Request> Future for ServiceFuture<S, L, Target, Request>
where where
S: MakeService<Target, Request>, S: MakeService<Target, Request>,
S::MakeError: Into<Error>, L: Layer<S::Service>,
L: Layer<S::Service, Request>,
L::LayerError: Into<Error>,
{ {
type Item = L::Service; type Item = L::Service;
type Error = Error; type Error = S::MakeError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let service = try_ready!(self.inner.poll().map_err(Into::into)); let service = try_ready!(self.inner.poll());
let service = self.layer.layer(service);
match self.layer.layer(service) { Ok(Async::Ready(service))
Ok(service) => Ok(Async::Ready(service)),
Err(e) => Err(e.into()),
}
} }
} }

View File

@ -37,8 +37,7 @@ fn builder_service() {
.layer(BufferLayer::new(5)) .layer(BufferLayer::new(5))
.layer(ConcurrencyLimitLayer::new(5)) .layer(ConcurrencyLimitLayer::new(5))
.layer(RateLimitLayer::new(5, Duration::from_secs(1))) .layer(RateLimitLayer::new(5, Duration::from_secs(1)))
.service(MockSvc) .service(MockSvc);
.unwrap();
client.poll_ready().unwrap(); client.poll_ready().unwrap();
client client