diff --git a/Cargo.toml b/Cargo.toml index 52dd247..454ad61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ members = [ "tower-in-flight-limit", "tower-mock", "tower-rate-limit", - "tower-ready-service", "tower-reconnect", "tower-router", "tower-service", diff --git a/tower-in-flight-limit/Cargo.toml b/tower-in-flight-limit/Cargo.toml index 5b8d478..4e90b6c 100644 --- a/tower-in-flight-limit/Cargo.toml +++ b/tower-in-flight-limit/Cargo.toml @@ -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" } diff --git a/tower-in-flight-limit/src/lib.rs b/tower-in-flight-limit/src/lib.rs index 2caabca..303a41f 100644 --- a/tower-in-flight-limit/src/lib.rs +++ b/tower-in-flight-limit/src/lib.rs @@ -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}; @@ -79,29 +77,6 @@ impl InFlightLimit { pub fn into_inner(self) -> T { self.inner } - - fn call2(&mut self, f: F) -> ResponseFuture - 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 Service for InFlightLimit @@ -131,20 +106,24 @@ where S: Service } fn call(&mut self, request: Self::Request) -> Self::Future { - self.call2(|me| me.inner.call(request)) - } -} + // 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(), + }; + } + } -impl ReadyService for InFlightLimit -where S: ReadyService -{ - type Request = S::Request; - type Response = S::Response; - type Error = Error; - type Future = ResponseFuture; - - 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(), + } } } diff --git a/tower-ready-service/Cargo.toml b/tower-ready-service/Cargo.toml deleted file mode 100644 index a78d7eb..0000000 --- a/tower-ready-service/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "tower-ready-service" -version = "0.1.0" -authors = ["Carl Lerche "] -publish = false - -[dependencies] -futures = "0.1" -tower-service = { version = "0.1", path = "../tower-service" } diff --git a/tower-ready-service/README.md b/tower-ready-service/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/tower-ready-service/src/lib.rs b/tower-ready-service/src/lib.rs deleted file mode 100644 index 029ec72..0000000 --- a/tower-ready-service/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern crate tower_service; - -pub use tower_service::ReadyService; diff --git a/tower-service/src/lib.rs b/tower-service/src/lib.rs index 5bde76c..a5a10c2 100644 --- a/tower-service/src/lib.rs +++ b/tower-service/src/lib.rs @@ -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; - - /// 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; } diff --git a/tower-util/Cargo.toml b/tower-util/Cargo.toml index 4b073d8..3b00d70 100644 --- a/tower-util/Cargo.toml +++ b/tower-util/Cargo.toml @@ -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" } diff --git a/tower-util/src/lib.rs b/tower-util/src/lib.rs index bca74c3..245de34 100644 --- a/tower-util/src/lib.rs +++ b/tower-util/src/lib.rs @@ -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; @@ -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; diff --git a/tower-util/src/service_fn.rs b/tower-util/src/service_fn.rs index 7df0ce0..41e90a7 100644 --- a/tower-util/src/service_fn.rs +++ b/tower-util/src/service_fn.rs @@ -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 { - f: T, - // don't impose Sync on R - _ty: PhantomData R>, -} - /// A `NewService` implemented by a closure. pub struct NewServiceFn { f: T, } -// ===== impl ServiceFn ===== - -impl ServiceFn -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 ReadyService for ServiceFn -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 NewServiceFn