Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ReadyService #68

Merged
merged 3 commits into from
Apr 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ members = [
"tower-in-flight-limit",
"tower-mock",
"tower-rate-limit",
"tower-ready-service",
"tower-reconnect",
"tower-router",
"tower-service",
Expand Down
1 change: 0 additions & 1 deletion tower-in-flight-limit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ publish = false
[dependencies]
futures = "0.1"
tower-service = { version = "0.1", path = "../tower-service" }
tower-ready-service = { version = "0.1", path = "../tower-ready-service" }

[dev-dependencies]
tower-mock = { version = "0.1", path = "../tower-mock" }
55 changes: 17 additions & 38 deletions tower-in-flight-limit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
//! service.

extern crate futures;
extern crate tower_ready_service;
extern crate tower_service;

use tower_ready_service::ReadyService;
use tower_service::Service;

use futures::{Future, Poll, Async};
Expand Down Expand Up @@ -79,29 +77,6 @@ impl<T> InFlightLimit<T> {
pub fn into_inner(self) -> T {
self.inner
}

fn call2<F, R>(&mut self, f: F) -> ResponseFuture<R>
where F: FnOnce(&mut Self) -> R,
{
// In this implementation, `poll_ready` is not expected to be called
// first (though, it might have been).
if self.state.reserved {
self.state.reserved = false;
} else {
// Try to reserve
if !self.state.shared.reserve() {
return ResponseFuture {
inner: None,
shared: self.state.shared.clone(),
};
}
}

ResponseFuture {
inner: Some(f(self)),
shared: self.state.shared.clone(),
}
}
}

impl<S> Service for InFlightLimit<S>
Expand Down Expand Up @@ -131,20 +106,24 @@ where S: Service
}

fn call(&mut self, request: Self::Request) -> Self::Future {
self.call2(|me| me.inner.call(request))
}
}

impl<S> ReadyService for InFlightLimit<S>
where S: ReadyService
{
type Request = S::Request;
type Response = S::Response;
type Error = Error<S::Error>;
type Future = ResponseFuture<S::Future>;
// In this implementation, `poll_ready` is not expected to be called
// first (though, it might have been).
if self.state.reserved {
self.state.reserved = false;
} else {
// Try to reserve
if !self.state.shared.reserve() {
return ResponseFuture {
inner: None,
shared: self.state.shared.clone(),
};
}
}

fn call(&mut self, request: Self::Request) -> Self::Future {
self.call2(|me| me.inner.call(request))
ResponseFuture {
inner: Some(self.inner.call(request)),
shared: self.state.shared.clone(),
}
}
}

Expand Down
9 changes: 0 additions & 9 deletions tower-ready-service/Cargo.toml

This file was deleted.

Empty file removed tower-ready-service/README.md
Empty file.
3 changes: 0 additions & 3 deletions tower-ready-service/src/lib.rs

This file was deleted.

44 changes: 3 additions & 41 deletions tower-service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,47 +189,9 @@ pub trait Service {
/// implementations should take care to not call `poll_ready`. If the
/// service is at capacity and the request is unable to be handled, the
/// returned `Future` should resolve to an error.
fn call(&mut self, req: Self::Request) -> Self::Future;
}

/// An asynchronous function from `Request` to a `Response` that is always ready
/// to process a request.
///
/// `ReadyService` is similar to `Service`, except that it is always able to
/// accept a request. This request may either complete successfully or resolve
/// to an error, i.e., `ReadyService` implementations may handle out of capacity
/// situations by returning a response future that immediately resolves to an
/// error.
///
/// The `Service` trait should be prefered over this one. `ReadyService` should
/// only be used in situations where there is no way to handle back pressure.
/// When usin a `ReadyService` implementation, back pressure needs to be handled
/// via some other strategy, such as limiting the total number of in flight
/// requests.
///
/// One situation in which there is no way to handle back pressure is routing.
/// A router service receives inbound requests and dispatches them to one of N
/// inner services. In this case, one of the inner services may become "not
/// ready" while the others remain ready. It would not be ideal for the router
/// service to flag itself as "not ready" when only one of the inner services is
/// not ready, but there is no way for the router to communicate to the caller
/// which requests will be accepted and which will be rejected. The router
/// service will implement `ReadyService`, indicating to the user that they are
/// responsible for handling back pressure via some other strategy.
pub trait ReadyService {
/// Requests handled by the service.
type Request;

/// Responses returned by the service.
type Response;

/// Errors produced by the service.
type Error;

/// The future response value.
type Future: Future<Item = Self::Response, Error = Self::Error>;

/// Process the request and return the response asynchronously.
///
/// Calling `call` without calling `poll_ready` is permitted. The
/// implementation must be resilient to this fact.
fn call(&mut self, req: Self::Request) -> Self::Future;
}

Expand Down
1 change: 0 additions & 1 deletion tower-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ publish = false
[dependencies]
futures = "0.1"
tower-service = { version = "0.1", path = "../tower-service" }
tower-ready-service = { version = "0.1", path = "../tower-ready-service" }
3 changes: 1 addition & 2 deletions tower-util/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Various utility types and functions that are generally with Tower.

extern crate futures;
extern crate tower_ready_service;
extern crate tower_service;

pub mod either;
Expand All @@ -11,5 +10,5 @@ mod service_fn;

pub use boxed::BoxService;
pub use either::EitherService;
pub use service_fn::{ServiceFn, NewServiceFn};
pub use service_fn::{NewServiceFn};
pub use option::OptionService;
40 changes: 0 additions & 40 deletions tower-util/src/service_fn.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,11 @@
use futures::IntoFuture;
use tower_ready_service::ReadyService;
use tower_service::{Service, NewService};

use std::marker::PhantomData;

/// A `Service` implemented by a closure.
#[derive(Debug, Clone)]
pub struct ServiceFn<T, R> {
f: T,
// don't impose Sync on R
_ty: PhantomData<fn() -> R>,
}

/// A `NewService` implemented by a closure.
pub struct NewServiceFn<T> {
f: T,
}

// ===== impl ServiceFn =====

impl<T, R, S> ServiceFn<T, R>
where T: FnMut(R) -> S,
S: IntoFuture,
{
/// Create a new `ServiceFn` backed by the given closure
pub fn new(f: T) -> Self {
ServiceFn {
f,
_ty: PhantomData,
}
}
}

impl<T, R, S> ReadyService for ServiceFn<T, R>
where T: FnMut(R) -> S,
S: IntoFuture,
{
type Request = R;
type Response = S::Item;
type Error = S::Error;
type Future = S::Future;

fn call(&mut self, request: Self::Request) -> Self::Future {
(self.f)(request).into_future()
}
}

// ===== impl NewServiceFn =====

impl<T, N> NewServiceFn<T>
Expand Down