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 std::marker::PhantomData;
use tokio_executor::DefaultExecutor;
use tower_layer::Layer;
use tower_service::Service;
/// Buffer requests with a bounded buffer
pub struct BufferLayer<E = DefaultExecutor> {
pub struct BufferLayer<Request, E = DefaultExecutor> {
bound: usize,
executor: E,
_p: PhantomData<fn(Request)>,
}
impl BufferLayer<DefaultExecutor> {
impl<Request> BufferLayer<Request, DefaultExecutor> {
pub fn new(bound: usize) -> Self {
BufferLayer {
bound,
executor: DefaultExecutor::current(),
_p: PhantomData,
}
}
}
impl<E> BufferLayer<E> {
pub fn with_executor<S, Request>(bound: usize, executor: E) -> Self
where
S: Service<Request>,
S::Error: Into<Error>,
E: WorkerExecutor<S, Request> + Clone,
{
BufferLayer { bound, executor }
impl<Request, E: Clone> BufferLayer<Request, E> {
pub fn with_executor(bound: usize, executor: E) -> Self {
BufferLayer {
bound,
executor,
_p: PhantomData,
}
}
}
impl<E, S, Request> Layer<S, Request> for BufferLayer<E>
impl<E, S, Request> Layer<S> for BufferLayer<Request, E>
where
S: Service<Request>,
S::Error: Into<Error>,
E: WorkerExecutor<S, Request> + Clone,
{
type Response = S::Response;
type Error = Error;
type LayerError = Error;
type Service = Buffer<S, Request>;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> {
Ok(Buffer::with_executor(
service,
self.bound,
&mut self.executor.clone(),
))
fn layer(&self, service: S) -> Self::Service {
Buffer::with_executor(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::{
error::{self, Error},
Filter, Predicate,
};
use crate::Filter;
use tower_layer::Layer;
use tower_service::Service;
pub struct FilterLayer<U> {
predicate: U,
@ -15,19 +11,11 @@ impl<U> FilterLayer<U> {
}
}
impl<U, S, Request> Layer<S, Request> 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;
impl<U: Clone, S> Layer<S> for FilterLayer<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();
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> {
pub fn new<Request>(inner: T, predicate: U) -> Self
where
T: Service<Request> + Clone,
T::Error: Into<error::Source>,
U: Predicate<Request>,
{
pub fn new(inner: T, predicate: U) -> Self {
Filter { inner, predicate }
}
}

View File

@ -8,8 +8,6 @@
//!
//! A middleware implements the [`Layer`] and [`Service`] trait.
use tower_service::Service;
/// Decorates a `Service`, transforming either the request or the response.
///
/// Often, many of the pieces needed for writing network applications can be
@ -36,21 +34,14 @@ use tower_service::Service;
/// target: &'static str,
/// }
///
/// impl<S, Request> Layer<S, Request> for LogLayer
/// where
/// S: Service<Request>,
/// Request: fmt::Debug,
/// {
/// type Response = S::Response;
/// type Error = S::Error;
/// type LayerError = Void;
/// impl<S> Layer<S> for LogLayer {
/// type Service = LogService<S>;
///
/// fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> {
/// Ok(LogService {
/// fn layer(&self, service: S) -> Self::Service {
/// LogService {
/// target: self.target,
/// service
/// })
/// }
/// }
/// }
///
@ -84,20 +75,10 @@ use tower_service::Service;
/// The above log implementation is decoupled from the underlying protocol and
/// 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.
pub trait Layer<S, Request> {
/// The wrapped service response type
type Response;
/// The wrapped service's error type
type Error;
/// The error produced when calling `layer`
type LayerError;
pub trait Layer<S> {
/// 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
/// 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_service::Service;
#[derive(Debug, Clone)]
pub struct ConcurrencyLimitLayer {
@ -13,17 +12,10 @@ impl ConcurrencyLimitLayer {
}
}
impl<S, Request> Layer<S, Request> for ConcurrencyLimitLayer
where
S: Service<Request>,
S::Error: Into<Error>,
{
type Response = S::Response;
type Error = Error;
type LayerError = Never;
impl<S> Layer<S> for ConcurrencyLimitLayer {
type Service = ConcurrencyLimit<S>;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> {
Ok(ConcurrencyLimit::new(service, self.max))
fn layer(&self, service: S) -> Self::Service {
ConcurrencyLimit::new(service, self.max)
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
#![deny(warnings)]
// #![deny(warnings)]
#![deny(rust_2018_idioms)]
#![allow(elided_lifetimes_in_paths)]
@ -11,9 +11,6 @@ use tower_layer::Layer;
use tower_service::Service;
pub mod budget;
mod never;
use crate::never::Never;
/// 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
S: Service<Request> + Clone,
P: Policy<Request, S::Response, S::Error> + Clone,
P: Clone,
{
type Response = S::Response;
type Error = S::Error;
type LayerError = Never;
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();
Ok(Retry::new(policy, service))
Retry::new(policy, service)
}
}
@ -147,11 +140,7 @@ where
impl<P, S> Retry<P, S> {
/// Retry the inner service depending on this [`Policy`][Policy}.
pub fn new<Request>(policy: P, service: S) -> Self
where
P: Policy<Request, S::Response, S::Error> + Clone,
S: Service<Request> + Clone,
{
pub fn new(policy: P, service: S) -> Self {
Retry { policy, service }
}
}

View File

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

View File

@ -11,7 +11,6 @@
pub mod error;
pub mod future;
mod layer;
mod never;
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_service::Service;
/// A no-op middleware.
///
@ -19,28 +17,10 @@ impl Identity {
}
/// Decorates a `Service`, transforming either the request or the response.
impl<S, Request> Layer<S, Request> for Identity
where
S: Service<Request>,
{
type Response = S::Response;
type Error = S::Error;
type LayerError = Never;
impl<S> Layer<S> for Identity {
type Service = S;
fn layer(&self, inner: S) -> Result<Self::Service, Self::LayerError> {
Ok(inner)
fn layer(&self, inner: S) -> Self::Service {
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_service::Service;
/// Two middlewares chained together.
///
@ -10,8 +9,6 @@ pub struct Stack<Inner, Outer> {
outer: Outer,
}
type Error = Box<dyn std::error::Error + Send + Sync>;
impl<Inner, Outer> Stack<Inner, Outer> {
/// Create a new `Stack`.
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
S: Service<Request>,
Inner: Layer<S, Request>,
Inner::LayerError: Into<Error>,
Outer: Layer<Inner::Service, Request>,
Outer::LayerError: Into<Error>,
Inner: Layer<S>,
Outer: Layer<Inner::Service>,
{
type Response = Outer::Response;
type Error = Outer::Error;
type LayerError = Error;
type Service = Outer::Service;
fn layer(&self, service: S) -> Result<Self::Service, Self::LayerError> {
let inner = self.inner.layer(service).map_err(Into::into)?;
fn layer(&self, service: S) -> Self::Service {
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>>,
/// # {
/// ServiceBuilder::new()
/// .buffer(100)
/// // .buffer(100)
/// .concurrency_limit(10)
/// .service(my_service)
/// # ;
@ -96,7 +96,7 @@ pub(super) type Error = Box<dyn std::error::Error + Send + Sync>;
/// # {
/// ServiceBuilder::new()
/// .concurrency_limit(10)
/// .buffer(100)
/// // .buffer(100)
/// .service(my_service)
/// # ;
/// # }
@ -207,12 +207,12 @@ pub(super) type Error = Box<dyn std::error::Error + Send + Sync>;
/// # }
/// # }
/// ServiceBuilder::new()
/// .buffer(5)
/// // .buffer(5)
/// .concurrency_limit(5)
/// .rate_limit(5, Duration::from_secs(1))
/// .service(MyService);
/// ```
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct ServiceBuilder<L> {
layer: L,
}
@ -235,7 +235,7 @@ impl<L> ServiceBuilder<L> {
}
/// 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))
}
@ -291,10 +291,10 @@ impl<L> ServiceBuilder<L> {
}
/// 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
L: Layer<S, Request>,
S: Service<Request>,
L: Layer<S>,
L::Service: Service<Request>,
{
self.layer.layer(service)
}

View File

@ -1,4 +1,3 @@
use super::Error;
use crate::Service;
use futures::{try_ready, Async, Future, Poll};
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>
where
S: MakeService<Target, Request>,
S::MakeError: Into<Error>,
L: Layer<S::Service, Request> + Sync + Send + 'static,
L::LayerError: Into<Error>,
L: Layer<S::Service> + Sync + Send + 'static,
Target: Clone,
{
type Response = L::Service;
type Error = Error;
type Error = S::MakeError;
type Future = ServiceFuture<S, L, Target, Request>;
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 {
@ -60,19 +57,14 @@ where
impl<S, L, Target, Request> Future for ServiceFuture<S, L, Target, Request>
where
S: MakeService<Target, Request>,
S::MakeError: Into<Error>,
L: Layer<S::Service, Request>,
L::LayerError: Into<Error>,
L: Layer<S::Service>,
{
type Item = L::Service;
type Error = Error;
type Error = S::MakeError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let service = try_ready!(self.inner.poll().map_err(Into::into));
match self.layer.layer(service) {
Ok(service) => Ok(Async::Ready(service)),
Err(e) => Err(e.into()),
}
let service = try_ready!(self.inner.poll());
let service = self.layer.layer(service);
Ok(Async::Ready(service))
}
}

View File

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