Update all tower pieces to use Service<Request> (#132)

Signed-off-by: Sean McArthur <sean@buoyant.io>
This commit is contained in:
Sean McArthur 2018-11-16 11:19:17 -08:00 committed by Oliver Gould
parent 7add0db68e
commit f37c9e5128
45 changed files with 716 additions and 559 deletions

View File

@ -113,9 +113,9 @@ dependencies = [
[[package]]
name = "codegen"
version = "0.1.0"
source = "git+https://github.com/carllerche/codegen#9b2f81859e91931871456ad06437643585d35866"
source = "git+https://github.com/carllerche/codegen#2d4dcc96f530ba163674d5efa985c3b133b3022e"
dependencies = [
"indexmap 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -304,7 +304,7 @@ dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"string 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -381,7 +381,7 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.0.0"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -500,7 +500,7 @@ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.9 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quickcheck 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -523,7 +523,7 @@ dependencies = [
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.9 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"inotify 0.5.2-dev (git+https://github.com/inotify-rs/inotify)",
"ipnet 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
@ -558,6 +558,7 @@ dependencies = [
"tower-grpc 0.1.0 (git+https://github.com/tower-rs/tower-grpc)",
"tower-h2 0.1.0 (git+https://github.com/tower-rs/tower-h2)",
"tower-h2-balance 0.1.0 (git+https://github.com/tower-rs/tower-h2)",
"tower-http 0.1.0 (git+https://github.com/tower-rs/tower-http)",
"tower-in-flight-limit 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-reconnect 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
@ -591,7 +592,7 @@ name = "linkerd2-router"
version = "0.1.0"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-stack 0.1.0",
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
]
@ -1303,7 +1304,7 @@ dependencies = [
[[package]]
name = "tower-add-origin"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower-http#c9e13f641a681b3ef01e96910789586e39aee2e2"
source = "git+https://github.com/tower-rs/tower-http#3599ce02f063cf7db5aae3edcdaeb9073a7ebc33"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1313,10 +1314,10 @@ dependencies = [
[[package]]
name = "tower-balance"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85"
source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1327,7 +1328,7 @@ dependencies = [
[[package]]
name = "tower-buffer"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85"
source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
@ -1336,7 +1337,7 @@ dependencies = [
[[package]]
name = "tower-discover"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85"
source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
@ -1345,7 +1346,7 @@ dependencies = [
[[package]]
name = "tower-grpc"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower-grpc#0afac3d409febe20db4432b5abe06dbd72bd4c95"
source = "git+https://github.com/tower-rs/tower-grpc#40b059abac9ca07edac252f4d0b69c55f6ecf88d"
dependencies = [
"bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1354,13 +1355,14 @@ dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"prost 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-h2 0.1.0 (git+https://github.com/tower-rs/tower-h2)",
"tower-http 0.1.0 (git+https://github.com/tower-rs/tower-http)",
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
]
[[package]]
name = "tower-grpc-build"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower-grpc#0afac3d409febe20db4432b5abe06dbd72bd4c95"
source = "git+https://github.com/tower-rs/tower-grpc#40b059abac9ca07edac252f4d0b69c55f6ecf88d"
dependencies = [
"codegen 0.1.0 (git+https://github.com/carllerche/codegen)",
"heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1370,7 +1372,7 @@ dependencies = [
[[package]]
name = "tower-h2"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower-h2#1299be66fee7be919699d7c1edfb30adac03d4c1"
source = "git+https://github.com/tower-rs/tower-h2#9b96d8d5eabe56a44a7d01228b14e96d875e84b3"
dependencies = [
"bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1385,7 +1387,7 @@ dependencies = [
[[package]]
name = "tower-h2-balance"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower-h2#760f9fc1c83c3a96edb6fbddb6b0cd3cac73d8ac"
source = "git+https://github.com/tower-rs/tower-h2#9b96d8d5eabe56a44a7d01228b14e96d875e84b3"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1395,10 +1397,21 @@ dependencies = [
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
]
[[package]]
name = "tower-http"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower-http#3599ce02f063cf7db5aae3edcdaeb9073a7ebc33"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-add-origin 0.1.0 (git+https://github.com/tower-rs/tower-http)",
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
]
[[package]]
name = "tower-in-flight-limit"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85"
source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
@ -1407,7 +1420,7 @@ dependencies = [
[[package]]
name = "tower-reconnect"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85"
source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1417,7 +1430,7 @@ dependencies = [
[[package]]
name = "tower-service"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85"
source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1425,7 +1438,7 @@ dependencies = [
[[package]]
name = "tower-util"
version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85"
source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
@ -1683,7 +1696,7 @@ dependencies = [
"checksum httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7b6288d7db100340ca12873fd4d08ad1b8f206a9457798dfb17c018a33fee540"
"checksum hyper 0.12.9 (registry+https://github.com/rust-lang/crates.io-index)" = "081289d17dce471c8cbc0e69a3dd073b627e08338561d1167ab620b754d9fe90"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum indexmap 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9378f1f3923647a9aea6af4c6b5de68cc8a71415459ad25ef191191c48f5b7"
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
"checksum inotify 0.5.2-dev (git+https://github.com/inotify-rs/inotify)" = "<none>"
"checksum inotify-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7dceb94c43f70baf4c4cd6afbc1e9037d4161dbe68df8a2cd4351a23319ee4fb"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
@ -1780,6 +1793,7 @@ dependencies = [
"checksum tower-grpc-build 0.1.0 (git+https://github.com/tower-rs/tower-grpc)" = "<none>"
"checksum tower-h2 0.1.0 (git+https://github.com/tower-rs/tower-h2)" = "<none>"
"checksum tower-h2-balance 0.1.0 (git+https://github.com/tower-rs/tower-h2)" = "<none>"
"checksum tower-http 0.1.0 (git+https://github.com/tower-rs/tower-http)" = "<none>"
"checksum tower-in-flight-limit 0.1.0 (git+https://github.com/tower-rs/tower)" = "<none>"
"checksum tower-reconnect 0.1.0 (git+https://github.com/tower-rs/tower)" = "<none>"
"checksum tower-service 0.1.0 (git+https://github.com/tower-rs/tower)" = "<none>"

View File

@ -65,6 +65,7 @@ tower-in-flight-limit = { git = "https://github.com/tower-rs/tower" }
tower-reconnect = { git = "https://github.com/tower-rs/tower" }
tower-service = { git = "https://github.com/tower-rs/tower" }
tower-util = { git = "https://github.com/tower-rs/tower" }
tower-http = { git = "https://github.com/tower-rs/tower-http" }
tower-h2 = { git = "https://github.com/tower-rs/tower-h2" }
tower-h2-balance = { git = "https://github.com/tower-rs/tower-h2" }
tower-grpc = { git = "https://github.com/tower-rs/tower-grpc" }

View File

@ -19,7 +19,7 @@ pub struct Router<Req, Rec, Stk>
where
Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>,
Stk::Value: svc::Service<Req>,
{
inner: Arc<Inner<Req, Rec, Stk>>,
}
@ -57,7 +57,7 @@ struct Inner<Req, Rec, Stk>
where
Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>,
Stk::Value: svc::Service<Req>,
{
recognize: Rec,
make: Stk,
@ -95,7 +95,7 @@ impl<Req, Rec, Stk> Router<Req, Rec, Stk>
where
Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>,
Stk::Value: svc::Service<Req>,
{
pub fn new(recognize: Rec, make: Stk, capacity: usize, max_idle_age: Duration) -> Self {
Router {
@ -108,16 +108,15 @@ where
}
}
impl<Req, Rec, Stk> svc::Service for Router<Req, Rec, Stk>
impl<Req, Rec, Stk> svc::Service<Req> for Router<Req, Rec, Stk>
where
Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>,
Stk::Value: svc::Service<Req>,
{
type Request = <Stk::Value as svc::Service>::Request;
type Response = <Stk::Value as svc::Service>::Response;
type Error = Error<<Stk::Value as svc::Service>::Error, Stk::Error>;
type Future = ResponseFuture<<Stk::Value as svc::Service>::Future, Stk::Error>;
type Response = <Stk::Value as svc::Service<Req>>::Response;
type Error = Error<<Stk::Value as svc::Service<Req>>::Error, Stk::Error>;
type Future = ResponseFuture<<Stk::Value as svc::Service<Req>>::Future, Stk::Error>;
/// Always ready to serve.
///
@ -133,7 +132,7 @@ where
/// Routes the request through an underlying service.
///
/// The response fails when the request cannot be routed.
fn call(&mut self, request: Self::Request) -> Self::Future {
fn call(&mut self, request: Req) -> Self::Future {
let target = match self.inner.recognize.recognize(&request) {
Some(target) => target,
None => return ResponseFuture::not_recognized(),
@ -172,7 +171,7 @@ impl<Req, Rec, Stk> Clone for Router<Req, Rec, Stk>
where
Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>,
Stk::Value: svc::Service<Req>,
{
fn clone(&self) -> Self {
Router { inner: self.inner.clone() }
@ -311,8 +310,7 @@ mod test_util {
}
}
impl Service for MultiplyAndAssign {
type Request = Request;
impl Service<Request> for MultiplyAndAssign {
type Response = usize;
type Error = ();
type Future = future::FutureResult<usize, ()>;
@ -321,7 +319,7 @@ mod test_util {
unimplemented!()
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: Request) -> Self::Future {
let n = match req {
Request::NotRecognized => unreachable!(),
Request::Recognized(n) => n,

View File

@ -44,12 +44,11 @@ where
}
}
impl<A, B> svc::Service for Either<A, B>
impl<A, B, R> svc::Service<R> for Either<A, B>
where
A: svc::Service,
B: svc::Service<Request = A::Request, Response = A::Response>,
A: svc::Service<R>,
B: svc::Service<R, Response = A::Response>,
{
type Request = A::Request;
type Response = A::Response;
type Error = Either<A::Error, B::Error>;
type Future = future::Either<
@ -64,7 +63,7 @@ where
}
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: R) -> Self::Future {
match self {
Either::A(ref mut a) => future::Either::A(a.call(req).map_err(Either::A)),
Either::B(ref mut b) => future::Either::B(b.call(req).map_err(Either::B)),

View File

@ -9,13 +9,13 @@ pub mod layer;
mod map_err;
pub mod map_target;
pub mod phantom_data;
pub mod stack_new_service;
pub mod stack_make_service;
pub mod stack_per_request;
pub mod watch;
pub use self::either::Either;
pub use self::layer::Layer;
pub use self::stack_new_service::StackNewService;
pub use self::stack_make_service::StackMakeService;
/// A composable builder.
///

View File

@ -0,0 +1,37 @@
use futures::{future, Poll};
use svc;
use super::Stack;
/// Implements `MakeService` using a `Stack` of `Service`.
#[derive(Clone, Debug)]
pub struct StackMakeService<T, M: Stack<T>> {
make: M,
target: T,
}
impl<T, M> StackMakeService<T, M>
where
M: Stack<T>,
{
pub fn new(make: M, target: T) -> Self {
Self { make, target }
}
}
impl<T, M> svc::Service<()> for StackMakeService<T, M>
where
M: Stack<T>,
{
type Response = M::Value;
type Error = M::Error;
type Future = future::FutureResult<Self::Response, Self::Error>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(().into())
}
fn call(&mut self, _target: ()) -> Self::Future {
future::result(self.make.make(&self.target))
}
}

View File

@ -1,38 +0,0 @@
use futures::future;
use svc;
use super::Stack;
/// Implements `NewService` using a `Stack` of `Service`.
#[derive(Clone, Debug)]
pub struct StackNewService<T, M: Stack<T>> {
make: M,
target: T,
}
impl<T, M> StackNewService<T, M>
where
M: Stack<T>,
M::Value: svc::Service,
{
pub fn new(make: M, target: T) -> StackNewService<T, M> {
Self { make, target }
}
}
impl<T, M> svc::NewService for StackNewService<T, M>
where
M: Stack<T>,
M::Value: svc::Service,
{
type Request = <M::Value as svc::Service>::Request;
type Response = <M::Value as svc::Service>::Response;
type Error = <M::Value as svc::Service>::Error;
type Service = M::Value;
type InitError = M::Error;
type Future = future::FutureResult<Self::Service, Self::InitError>;
fn new_service(&self) -> Self::Future {
future::result(self.make.make(&self.target))
}
}

View File

@ -90,17 +90,16 @@ where
// === Service ===
impl<T, N> svc::Service for Service<T, N>
impl<T, N, R> svc::Service<R> for Service<T, N>
where
T: ShouldStackPerRequest + Clone,
N: super::Stack<T> + Clone,
N::Value: svc::Service,
N::Value: svc::Service<R>,
N::Error: fmt::Debug,
{
type Request = <N::Value as svc::Service>::Request;
type Response = <N::Value as svc::Service>::Response;
type Error = <N::Value as svc::Service>::Error;
type Future = <N::Value as svc::Service>::Future;
type Response = <N::Value as svc::Service<R>>::Response;
type Error = <N::Value as svc::Service<R>>::Error;
type Future = <N::Value as svc::Service<R>>::Future;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
if let Some(ref mut svc) = self.next {
@ -114,7 +113,7 @@ where
Ok(ready)
}
fn call(&mut self, request: Self::Request) -> Self::Future {
fn call(&mut self, request: R) -> Self::Future {
// If a service has already been bound in `poll_ready`, consume it.
// Otherwise, bind a new service on-the-spot.
self.next

View File

@ -120,18 +120,17 @@ where
// === impl Service ===
impl<T, U, M> svc::Service for Service<T, U, M>
impl<T, U, M, R> svc::Service<R> for Service<T, U, M>
where
T: WithUpdate<U>,
M: super::Stack<T::Updated>,
M::Value: svc::Service,
M::Value: svc::Service<R>,
{
type Request = <M::Value as svc::Service>::Request;
type Response = <M::Value as svc::Service>::Response;
type Error = Error<<M::Value as svc::Service>::Error, M::Error>;
type Response = <M::Value as svc::Service<R>>::Response;
type Error = Error<<M::Value as svc::Service<R>>::Error, M::Error>;
type Future = MapErr<
<M::Value as svc::Service>::Future,
fn(<M::Value as svc::Service>::Error) -> Self::Error,
<M::Value as svc::Service<R>>::Future,
fn(<M::Value as svc::Service<R>>::Error) -> Self::Error,
>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
@ -149,7 +148,7 @@ where
self.inner.poll_ready().map_err(Error::Inner)
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: R) -> Self::Future {
self.inner.call(req).map_err(Error::Inner)
}
}
@ -158,7 +157,6 @@ impl<U, M> Service<CloneUpdate, U, M>
where
U: Clone,
M: super::Stack<U>,
M::Value: svc::Service,
{
pub fn try(watch: Watch<U>, stack: M) -> Result<Self, M::Error> {
let inner = stack.make(&*watch.borrow())?;
@ -175,7 +173,7 @@ impl<T, U, M> Clone for Service<T, U, M>
where
T: WithUpdate<U> + Clone,
M: super::Stack<T::Updated> + Clone,
M::Value: svc::Service + Clone,
M::Value: Clone,
{
fn clone(&self) -> Self {
Self {
@ -227,8 +225,7 @@ mod tests {
#[test]
fn rebind() {
struct Svc(usize);
impl svc::Service for Svc {
type Request = ();
impl svc::Service<()> for Svc {
type Response = usize;
type Error = ();
type Future = future::FutureResult<usize, ()>;

View File

@ -69,11 +69,10 @@ impl<T> Timeout<T> {
}
}
impl<S, T, E> svc::Service for Timeout<S>
impl<S, T, E, Req> svc::Service<Req> for Timeout<S>
where
S: svc::Service<Response=T, Error=E>,
S: svc::Service<Req, Response=T, Error=E>,
{
type Request = S::Request;
type Response = T;
type Error = Error<E>;
type Future = Timeout<timer::Timeout<S::Future>>;
@ -82,7 +81,7 @@ where
self.inner.poll_ready().map_err(|e| self.error(e))
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: Req) -> Self::Future {
let inner = timer::Timeout::new(self.inner.call(req), self.duration);
Timeout {
inner,

View File

@ -162,7 +162,7 @@ pub mod resolve {
pub struct Init<M>
where
M: svc::Stack<client::Target>,
M::Value: svc::NewService,
M::Value: svc::Service<()>,
{
state: State<M>,
}
@ -170,14 +170,14 @@ pub mod resolve {
enum State<M>
where
M: svc::Stack<client::Target>,
M::Value: svc::NewService,
M::Value: svc::Service<()>,
{
Resolve {
future: dns::IpAddrFuture,
config: super::Config,
stack: M,
},
Inner(<M::Value as svc::NewService>::Future),
Inner(<M::Value as svc::Service<()>>::Future),
Invalid(Option<M::Error>),
}
@ -245,19 +245,20 @@ pub mod resolve {
// === impl NewService ===
impl<M> svc::NewService for NewService<M>
impl<M> svc::Service<()> for NewService<M>
where
M: svc::Stack<client::Target> + Clone,
M::Value: svc::NewService,
M::Value: svc::Service<()>,
{
type Request = <M::Value as svc::NewService>::Request;
type Response = <M::Value as svc::NewService>::Response;
type Error = <M::Value as svc::NewService>::Error;
type Service = <M::Value as svc::NewService>::Service;
type InitError = <Init<M> as Future>::Error;
type Response = <M::Value as svc::Service<()>>::Response;
type Error = <Init<M> as Future>::Error;
type Future = Init<M>;
fn new_service(&self) -> Self::Future {
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(().into())
}
fn call(&mut self, _target: ()) -> Self::Future {
let state = match self.config.addr {
Addr::Socket(sa) => State::make_inner(sa, &self.config, &self.stack),
Addr::Name(ref na) => State::Resolve {
@ -276,10 +277,10 @@ pub mod resolve {
impl<M> Future for Init<M>
where
M: svc::Stack<client::Target>,
M::Value: svc::NewService,
M::Value: svc::Service<()>,
{
type Item = <M::Value as svc::NewService>::Service;
type Error = Error<M::Error, <M::Value as svc::NewService>::InitError>;
type Item = <M::Value as svc::Service<()>>::Response;
type Error = Error<M::Error, <M::Value as svc::Service<()>>::Error>;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
loop {
@ -307,7 +308,7 @@ pub mod resolve {
impl<M> State<M>
where
M: svc::Stack<client::Target>,
M::Value: svc::NewService,
M::Value: svc::Service<()>,
{
fn make_inner(addr: SocketAddr, config: &super::Config, stack: &M) -> Self {
let tls = config.tls_server_identity.as_ref().and_then(|id| {
@ -327,7 +328,7 @@ pub mod resolve {
};
match stack.make(&target) {
Ok(n) => State::Inner(svc::NewService::new_service(&n)),
Ok(mut n) => State::Inner(svc::Service::call(&mut n, ())),
Err(e) => State::Invalid(Some(e)),
}
}
@ -353,7 +354,8 @@ pub mod resolve {
pub mod client {
use h2;
use std::marker::PhantomData;
use tower_h2::{client, BoxBody};
use tower_h2::client;
use tower_grpc::BoxBody;
use svc;
use transport::connect;
@ -442,10 +444,11 @@ pub mod client {
}
pub mod box_request_body {
use bytes::Bytes;
use http;
use futures::Poll;
use std::marker::PhantomData;
use tower_h2::{Body, BoxBody};
use tower_grpc::{Body, BoxBody};
use svc;
@ -481,9 +484,9 @@ pub mod box_request_body {
impl<B, T, M> svc::Layer<T, T, M> for Layer<B>
where
B: Body + Send + 'static,
B: Body<Data = Bytes> + Send + 'static,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<BoxBody<B::Data>>>,
M::Value: svc::Service<http::Request<BoxBody>>,
{
type Value = <Stack<B, M> as svc::Stack<T>>::Value;
type Error = <Stack<B, M> as svc::Stack<T>>::Error;
@ -507,9 +510,9 @@ pub mod box_request_body {
impl<B, T, M> svc::Stack<T> for Stack<B, M>
where
B: Body + Send + 'static,
B: Body<Data = Bytes> + Send + 'static,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<BoxBody<B::Data>>>,
M::Value: svc::Service<http::Request<BoxBody>>,
{
type Value = Service<B, M::Value>;
type Error = M::Error;
@ -522,12 +525,11 @@ pub mod box_request_body {
// === impl Service ===
impl<B, S> svc::Service for Service<B, S>
impl<B, S> svc::Service<http::Request<B>> for Service<B, S>
where
B: Body + Send + 'static,
S: svc::Service<Request = http::Request<BoxBody<B::Data>>>,
B: Body<Data = Bytes> + Send + 'static,
S: svc::Service<http::Request<BoxBody>>,
{
type Request = http::Request<B>;
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;

View File

@ -103,57 +103,75 @@ impl<A> router::Recognize<http::Request<A>> for RecognizeEndpoint {
}
pub mod orig_proto_downgrade {
use std::marker::PhantomData;
use http;
use proxy::http::orig_proto;
use proxy::server::Source;
use svc;
#[derive(Debug, Clone)]
pub struct Layer;
#[derive(Debug)]
pub struct Layer<A, B>(PhantomData<fn(A) -> B>);
#[derive(Clone, Debug)]
pub struct Stack<M>
where
M: svc::Stack<Source>,
{
#[derive(Debug)]
pub struct Stack<M, A, B> {
inner: M,
_marker: PhantomData<fn(A) -> B>,
}
// === impl Layer ===
pub fn layer() -> Layer {
Layer
pub fn layer<A, B>() -> Layer<A, B> {
Layer(PhantomData)
}
impl<M, A, B> svc::Layer<Source, Source, M> for Layer
impl<A, B> Clone for Layer<A, B> {
fn clone(&self) -> Self {
Layer(PhantomData)
}
}
impl<M, A, B> svc::Layer<Source, Source, M> for Layer<A, B>
where
M: svc::Stack<Source>,
M::Value: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
M::Value: svc::Service<http::Request<A>, Response = http::Response<B>>,
{
type Value = <Stack<M> as svc::Stack<Source>>::Value;
type Error = <Stack<M> as svc::Stack<Source>>::Error;
type Stack = Stack<M>;
type Value = <Stack<M, A, B> as svc::Stack<Source>>::Value;
type Error = <Stack<M, A, B> as svc::Stack<Source>>::Error;
type Stack = Stack<M, A, B>;
fn bind(&self, inner: M) -> Self::Stack {
Stack { inner }
Stack {
inner,
_marker: PhantomData,
}
}
}
// === impl Stack ===
impl<M, A, B> svc::Stack<Source> for Stack<M>
impl<M: Clone, A, B> Clone for Stack<M, A, B> {
fn clone(&self) -> Self {
Stack {
inner: self.inner.clone(),
_marker: PhantomData,
}
}
}
impl<M, A, B> svc::Stack<Source> for Stack<M, A, B>
where
M: svc::Stack<Source>,
M::Value: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
M::Value: svc::Service<http::Request<A>, Response = http::Response<B>>,
{
type Value = orig_proto::Downgrade<M::Value>;
type Error = M::Error;
fn make(&self, target: &Source) -> Result<Self::Value, Self::Error> {
info!("downgrading requests; source={:?}", target);
let inner = self.inner.make(&target)?;
Ok(inner.into())
self
.inner
.make(&target)
.map(orig_proto::Downgrade::new)
}
}
}

View File

@ -326,7 +326,7 @@ where
// request version and headers).
let endpoint_stack = client_stack
.push(buffer::layer())
.push(settings::router::layer::<Endpoint>())
.push(settings::router::layer::<Endpoint, _>())
.push(orig_proto_upgrade::layer())
.push(tap::layer(tap_next_id.clone(), taps.clone()))
.push(metrics::layer::<_, classify::Response>(
@ -476,7 +476,7 @@ where
// `default_fwd_addr` may be used.
let endpoint_router = client_stack
.push(buffer::layer())
.push(settings::router::layer::<Endpoint>())
.push(settings::router::layer::<Endpoint, _>())
.push(tap::layer(tap_next_id, taps))
.push(http_metrics::layer::<_, classify::Response>(
endpoint_http_metrics,
@ -655,10 +655,10 @@ where
<C::Value as connect::Connect>::Error: fmt::Debug + 'static,
R: svc::Stack<proxy::server::Source, Error = Never> + Send + Clone + 'static,
R::Value:
svc::Service<Request = http::Request<proxy::http::Body>, Response = http::Response<B>>,
svc::Service<http::Request<proxy::http::Body>, Response = http::Response<B>>,
R::Value: Send + 'static,
<R::Value as svc::Service>::Error: error::Error + Send + Sync + 'static,
<R::Value as svc::Service>::Future: Send + 'static,
<R::Value as svc::Service<http::Request<proxy::http::Body>>>::Error: error::Error + Send + Sync + 'static,
<R::Value as svc::Service<http::Request<proxy::http::Body>>>::Future: Send + 'static,
B: tower_h2::Body + Default + Send + 'static,
B::Data: Send,
<B::Data as ::bytes::IntoBuf>::Buf: Send,
@ -734,7 +734,7 @@ fn serve_tap<N, B>(
where
B: tower_h2::Body + Send + 'static,
<B::Data as bytes::IntoBuf>::Buf: Send,
N: svc::NewService<Request = http::Request<tower_h2::RecvBody>, Response = http::Response<B>>
N: svc::MakeService<(), http::Request<tower_h2::RecvBody>, Response = http::Response<B>>
+ Send
+ 'static,
tower_h2::server::Connection<Connection, N, ::logging::ServerExecutor, B, ()>:
@ -748,7 +748,7 @@ where
let log = log.clone();
// TODO: serve over TLS.
bound_port
.listen_and_fold(server, move |server, (session, remote)| {
.listen_and_fold(server, move |mut server, (session, remote)| {
let log = log.clone().with_remote(remote);
let serve = server.serve(session).map_err(|_| ());

View File

@ -159,54 +159,72 @@ pub mod discovery {
}
pub mod orig_proto_upgrade {
use std::marker::PhantomData;
use http;
use super::Endpoint;
use proxy::http::orig_proto;
use svc;
#[derive(Debug, Clone)]
pub struct Layer;
#[derive(Debug)]
pub struct Layer<A, B>(PhantomData<fn(A) -> B>);
#[derive(Clone, Debug)]
pub struct Stack<M>
where
M: svc::Stack<Endpoint>,
{
#[derive(Debug)]
pub struct Stack<M, A, B> {
inner: M,
_marker: PhantomData<fn(A) -> B>,
}
pub fn layer() -> Layer {
Layer
pub fn layer<A, B>() -> Layer<A, B> {
Layer(PhantomData)
}
impl<M, A, B> svc::Layer<Endpoint, Endpoint, M> for Layer
impl<A, B> Clone for Layer<A, B> {
fn clone(&self) -> Self {
Layer(PhantomData)
}
}
impl<M, A, B> svc::Layer<Endpoint, Endpoint, M> for Layer<A, B>
where
M: svc::Stack<Endpoint>,
M::Value: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
M::Value: svc::Service<http::Request<A>, Response = http::Response<B>>,
{
type Value = <Stack<M> as svc::Stack<Endpoint>>::Value;
type Error = <Stack<M> as svc::Stack<Endpoint>>::Error;
type Stack = Stack<M>;
type Value = <Stack<M, A, B> as svc::Stack<Endpoint>>::Value;
type Error = <Stack<M, A, B> as svc::Stack<Endpoint>>::Error;
type Stack = Stack<M, A, B>;
fn bind(&self, inner: M) -> Self::Stack {
Stack { inner }
Stack {
inner,
_marker: PhantomData,
}
}
}
// === impl Stack ===
impl<M, A, B> svc::Stack<Endpoint> for Stack<M>
impl<M: Clone, A, B> Clone for Stack<M, A, B> {
fn clone(&self) -> Self {
Stack {
inner: self.inner.clone(),
_marker: PhantomData,
}
}
}
impl<M, A, B> svc::Stack<Endpoint> for Stack<M, A, B>
where
M: svc::Stack<Endpoint>,
M::Value: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
M::Value: svc::Service<http::Request<A>, Response = http::Response<B>>,
{
type Value = svc::Either<orig_proto::Upgrade<M::Value>, M::Value>;
type Error = M::Error;
fn make(&self, endpoint: &Endpoint) -> Result<Self::Value, Self::Error> {
if endpoint.can_use_orig_proto() {
self.inner.make(&endpoint).map(|i| svc::Either::A(i.into()))
self.inner.make(&endpoint).map(|i| svc::Either::A(orig_proto::Upgrade::new(i)))
} else {
self.inner.make(&endpoint).map(svc::Either::B)
}

View File

@ -4,8 +4,8 @@ use regex::Regex;
use std::fmt;
use std::time::Duration;
use tokio_timer::{clock, Delay};
use tower_grpc as grpc;
use tower_h2::{Body, BoxBody, Data, HttpService};
use tower_grpc::{self as grpc, Body, BoxBody};
use tower_http::HttpService;
use api::destination as api;
@ -18,14 +18,22 @@ pub struct Client<T> {
backoff: Duration,
}
pub struct Rx<T: HttpService> {
pub struct Rx<T>
where
T: HttpService<BoxBody>,
T::ResponseBody: Body,
{
dst: String,
backoff: Duration,
service: Option<T>,
state: State<T>,
}
enum State<T: HttpService> {
enum State<T>
where
T: HttpService<BoxBody>,
T::ResponseBody: Body,
{
Disconnected,
Backoff(Delay),
Waiting(grpc::client::server_streaming::ResponseFuture<api::DestinationProfile, T::Future>),
@ -36,8 +44,8 @@ enum State<T: HttpService> {
impl<T> Client<T>
where
T: HttpService<RequestBody = BoxBody> + Clone,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody> + Clone,
T::ResponseBody: Body,
T::Error: fmt::Debug,
{
pub fn new(service: Option<T>, backoff: Duration) -> Self {
@ -50,8 +58,8 @@ where
impl<T> profiles::GetRoutes for Client<T>
where
T: HttpService<RequestBody = BoxBody> + Clone,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody> + Clone,
T::ResponseBody: Body,
T::Error: fmt::Debug,
{
type Stream = Rx<T>;
@ -70,8 +78,8 @@ where
impl<T> Stream for Rx<T>
where
T: HttpService<RequestBody = BoxBody> + Clone,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody> + Clone,
T::ResponseBody: Body,
T::Error: fmt::Debug,
{
type Item = Vec<(profiles::RequestMatch, profiles::Route)>;

View File

@ -8,7 +8,8 @@ use std::{
};
use futures::{Async, Future, Stream,};
use tower_h2::{Body, Data, HttpService};
use tower_http::HttpService;
use tower_grpc::{Body, BoxBody};
use api::{
destination::{
@ -31,7 +32,11 @@ use {Conditional, NameAddr};
use super::{ActiveQuery, DestinationServiceQuery, UpdateRx};
/// Holds the state of a single resolution.
pub(super) struct DestinationSet<T: HttpService> {
pub(super) struct DestinationSet<T>
where
T: HttpService<BoxBody>,
T::ResponseBody: Body,
{
pub addrs: Exists<Cache<SocketAddr, Metadata>>,
pub query: DestinationServiceQuery<T>,
pub dns_query: Option<IpAddrListFuture>,
@ -42,8 +47,8 @@ pub(super) struct DestinationSet<T: HttpService> {
impl<T> DestinationSet<T>
where
T: HttpService,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody>,
T::ResponseBody: Body,
T::Error: fmt::Debug,
{
pub(super) fn reset_dns_query(
@ -182,8 +187,8 @@ where
impl<T> DestinationSet<T>
where
T: HttpService,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody>,
T::ResponseBody: Body,
{
/// Returns `true` if the authority that created this query _should_ query
/// the Destination service, but was unable to due to insufficient capaacity.

View File

@ -12,8 +12,8 @@ use futures::{
sync::mpsc,
Async, Poll, Stream,
};
use tower_grpc as grpc;
use tower_h2::{Body, BoxBody, Data, HttpService};
use tower_grpc::{self as grpc, Body, BoxBody};
use tower_http::HttpService;
use api::destination::client::Destination;
use api::destination::{
@ -43,7 +43,11 @@ type UpdateRx<T> = Receiver<PbUpdate, T>;
/// service is healthy, it reads requests from `request_rx`, determines how to resolve the
/// provided authority to a set of addresses, and ensures that resolution updates are
/// propagated to all requesters.
pub(super) struct Background<T: HttpService> {
pub(super) struct Background<T>
where
T: HttpService<BoxBody>,
T::ResponseBody: Body,
{
new_query: NewQuery,
dns_resolver: dns::Resolver,
dsts: DestinationCache<T>,
@ -57,7 +61,11 @@ pub(super) struct Background<T: HttpService> {
/// Holds the currently active `DestinationSet`s and a list of any destinations
/// which require reconnects.
#[derive(Default)]
struct DestinationCache<T: HttpService> {
struct DestinationCache<T>
where
T: HttpService<BoxBody>,
T::ResponseBody: Body,
{
destinations: HashMap<NameAddr, DestinationSet<T>>,
/// A queue of authorities that need to be reconnected.
reconnects: VecDeque<NameAddr>,
@ -78,7 +86,11 @@ struct NewQuery {
concurrency_limit: usize,
}
enum DestinationServiceQuery<T: HttpService> {
enum DestinationServiceQuery<T>
where
T: HttpService<BoxBody>,
T::ResponseBody: Body,
{
Inactive,
Active(ActiveQuery<T>),
NoCapacity,
@ -88,8 +100,8 @@ enum DestinationServiceQuery<T: HttpService> {
impl<T> Background<T>
where
T: HttpService<RequestBody = BoxBody>,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody>,
T::ResponseBody: Body,
T::Error: fmt::Debug,
{
pub(super) fn new(
@ -344,8 +356,8 @@ impl NewQuery {
connect_or_reconnect: &str,
) -> DestinationServiceQuery<T>
where
T: HttpService<RequestBody = BoxBody>,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody>,
T::ResponseBody: Body,
T::Error: fmt::Debug,
{
trace!("DestinationServiceQuery {} {:?}", connect_or_reconnect, dst);
@ -396,8 +408,8 @@ impl NewQuery {
impl<T> DestinationCache<T>
where
T: HttpService,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody>,
T::ResponseBody: Body,
T::Error: fmt::Debug,
{
@ -433,8 +445,8 @@ where
impl<T> DestinationServiceQuery<T>
where
T: HttpService,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody>,
T::ResponseBody: Body,
{
pub fn is_active(&self) -> bool {
@ -461,8 +473,8 @@ where
impl<T> From<ActiveQuery<T>> for DestinationServiceQuery<T>
where
T: HttpService,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody>,
T::ResponseBody: Body,
{
fn from(active: ActiveQuery<T>) -> Self {
DestinationServiceQuery::Active(active)

View File

@ -35,7 +35,8 @@ use futures::{
use indexmap::IndexMap;
use std::fmt;
use std::sync::{Arc, Weak};
use tower_h2::{Body, BoxBody, Data, HttpService};
use tower_http::HttpService;
use tower_grpc::{Body, BoxBody};
use dns;
use transport::tls;
@ -118,8 +119,8 @@ pub fn new<T>(
concurrency_limit: usize,
) -> (Resolver, impl Future<Item = (), Error = ()>)
where
T: HttpService<RequestBody = BoxBody>,
T::ResponseBody: Body<Data = Data>,
T: HttpService<BoxBody>,
T::ResponseBody: Body,
T::Error: fmt::Debug,
{
let (request_tx, rx) = mpsc::unbounded();

View File

@ -46,7 +46,7 @@ impl server::Tap for Observe {
fn observe(&mut self, req: grpc::Request<ObserveRequest>) -> Self::ObserveFuture {
if self.next_id.load(Ordering::Acquire) == ::std::usize::MAX {
return future::err(grpc::Error::Grpc(
grpc::Status::INTERNAL,
grpc::Status::with_code(grpc::Code::Internal),
HeaderMap::new(),
));
}
@ -58,7 +58,7 @@ impl server::Tap for Observe {
Some(m) => m,
None => {
return future::err(grpc::Error::Grpc(
grpc::Status::INVALID_ARGUMENT,
grpc::Status::with_code(grpc::Code::InvalidArgument),
HeaderMap::new(),
));
}
@ -72,7 +72,7 @@ impl server::Tap for Observe {
}
Err(_) => {
return future::err(grpc::Error::Grpc(
grpc::Status::INTERNAL,
grpc::Status::with_code(grpc::Code::Internal),
HeaderMap::new(),
));
}

View File

@ -5,9 +5,11 @@ use std::{
fmt,
sync::Weak,
};
use tower_h2::{HttpService, Body, Data};
use tower_http::{HttpService};
use tower_grpc::{
self as grpc,
Body,
BoxBody,
Streaming,
client::server_streaming::ResponseFuture,
};
@ -16,7 +18,11 @@ use tower_grpc::{
///
/// A remote may hold a `Receiver` that can be used to read `M`-typed messages from the
/// remote stream.
pub enum Remote<M, S: HttpService> {
pub enum Remote<M, S>
where
S: HttpService<BoxBody>,
S::ResponseBody: Body,
{
NeedsReconnect,
ConnectedOrConnecting {
rx: Receiver<M, S>,
@ -28,7 +34,11 @@ pub enum Remote<M, S: HttpService> {
/// Streaming gRPC endpoints return a `ResponseFuture` whose item is a `Response<Stream>`.
/// A `Receiver` holds the state of that RPC call, exposing a `Stream` that drives both
/// the gRPC response and its streaming body.
pub struct Receiver<M, S: HttpService> {
pub struct Receiver<M, S>
where
S: HttpService<BoxBody>,
S::ResponseBody: Body,
{
rx: Rx<M, S>,
/// Used by `background::NewQuery` for counting the number of currently
@ -36,16 +46,20 @@ pub struct Receiver<M, S: HttpService> {
_active: Weak<()>,
}
enum Rx<M, S: HttpService> {
enum Rx<M, S>
where
S: HttpService<BoxBody>,
S::ResponseBody: Body,
{
Waiting(ResponseFuture<M, S::Future>),
Streaming(Streaming<M, S::ResponseBody>),
}
// ===== impl Receiver =====
impl<M: Message + Default, S: HttpService> Receiver<M, S>
impl<M: Message + Default, S: HttpService<BoxBody>> Receiver<M, S>
where
S::ResponseBody: Body<Data = Data>,
S::ResponseBody: Body,
S::Error: fmt::Debug,
{
pub fn new(future: ResponseFuture<M, S::Future>, active: Weak<()>) -> Self {
@ -66,15 +80,15 @@ where
// some reason does, we report this as an unknown error.
warn!("unexpected gRPC stream error");
debug_assert!(false);
grpc::Error::Grpc(grpc::Status::UNKNOWN, HeaderMap::new())
grpc::Error::Grpc(grpc::Status::with_code(grpc::Code::Unknown), HeaderMap::new())
}
}
}
}
impl<M: Message + Default, S: HttpService> Stream for Receiver<M, S>
impl<M: Message + Default, S: HttpService<BoxBody>> Stream for Receiver<M, S>
where
S::ResponseBody: Body<Data = Data>,
S::ResponseBody: Body,
S::Error: fmt::Debug,
{
type Item = M;

View File

@ -38,6 +38,7 @@ extern crate tokio;
extern crate tokio_timer;
extern crate tower_grpc;
extern crate tower_h2;
extern crate tower_http;
extern crate tower_util;
extern crate trust_dns_resolver;
extern crate try_lock;

View File

@ -1,6 +1,6 @@
extern crate tower_buffer;
use std::{error, fmt};
use std::{error, fmt, marker::PhantomData};
pub use self::tower_buffer::{Buffer, Error as ServiceError, SpawnError};
@ -8,13 +8,14 @@ use logging;
use svc;
/// Wraps `Service` stacks with a `Buffer`.
#[derive(Debug, Clone)]
pub struct Layer();
#[derive(Debug)]
pub struct Layer<Req>(PhantomData<fn(Req)>);
/// Produces `Service`s wrapped with a `Buffer`
#[derive(Debug, Clone)]
pub struct Stack<M> {
#[derive(Debug)]
pub struct Stack<M, Req> {
inner: M,
_marker: PhantomData<fn(Req)>,
}
pub enum Error<M, S> {
@ -24,38 +25,56 @@ pub enum Error<M, S> {
// === impl Layer ===
pub fn layer() -> Layer {
Layer()
pub fn layer<Req>() -> Layer<Req> {
Layer(PhantomData)
}
impl<T, M> svc::Layer<T, T, M> for Layer
impl<Req> Clone for Layer<Req> {
fn clone(&self) -> Self {
Layer(PhantomData)
}
}
impl<T, M, Req> svc::Layer<T, T, M> for Layer<Req>
where
T: fmt::Display + Clone + Send + Sync + 'static,
M: svc::Stack<T>,
M::Value: svc::Service + Send + 'static,
<M::Value as svc::Service>::Request: Send,
<M::Value as svc::Service>::Future: Send,
M::Value: svc::Service<Req> + Send + 'static,
<M::Value as svc::Service<Req>>::Future: Send,
Req: Send + 'static,
{
type Value = <Stack<M> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error;
type Stack = Stack<M>;
type Value = <Stack<M, Req> as svc::Stack<T>>::Value;
type Error = <Stack<M, Req> as svc::Stack<T>>::Error;
type Stack = Stack<M, Req>;
fn bind(&self, inner: M) -> Self::Stack {
Stack { inner }
Stack {
inner,
_marker: PhantomData,
}
}
}
// === impl Stack ===
impl<T, M> svc::Stack<T> for Stack<M>
impl<M: Clone, Req> Clone for Stack<M, Req> {
fn clone(&self) -> Self {
Stack {
inner: self.inner.clone(),
_marker: PhantomData,
}
}
}
impl<T, M, Req> svc::Stack<T> for Stack<M, Req>
where
T: fmt::Display + Clone + Send + Sync + 'static,
M: svc::Stack<T>,
M::Value: svc::Service + Send + 'static,
<M::Value as svc::Service>::Request: Send,
<M::Value as svc::Service>::Future: Send,
M::Value: svc::Service<Req> + Send + 'static,
<M::Value as svc::Service<Req>>::Future: Send,
Req: Send + 'static,
{
type Value = Buffer<M::Value>;
type Value = Buffer<M::Value, Req>;
type Error = Error<M::Error, M::Value>;
fn make(&self, target: &T) -> Result<Self::Value, Self::Error> {

View File

@ -74,7 +74,6 @@ pub fn layer(resolver: dns::Resolver) -> Layer {
impl<M> svc::Layer<Addr, Addr, M> for Layer
where
M: svc::Stack<Addr> + Clone,
M::Value: svc::Service,
{
type Value = <Stack<M> as svc::Stack<Addr>>::Value;
type Error = <Stack<M> as svc::Stack<Addr>>::Error;
@ -94,7 +93,6 @@ where
impl<M> svc::Stack<Addr> for Stack<M>
where
M: svc::Stack<Addr> + Clone,
M::Value: svc::Service,
{
type Value = svc::Either<Service<M>, M::Value>;
type Error = M::Error;
@ -120,7 +118,7 @@ where
impl<M> Service<M>
where
M: svc::Stack<Addr>,
M::Value: svc::Service,
//M::Value: svc::Service,
{
fn new(original: NameAddr, stack: M, resolver: dns::Resolver, timeout: Duration) -> Self {
trace!("refining name={}", original.name());
@ -205,17 +203,16 @@ where
}
}
impl<M> svc::Service for Service<M>
impl<M, Req> svc::Service<Req> for Service<M>
where
M: svc::Stack<Addr>,
M::Value: svc::Service,
M::Value: svc::Service<Req>,
{
type Request = <M::Value as svc::Service>::Request;
type Response = <M::Value as svc::Service>::Response;
type Error = Error<M::Error, <M::Value as svc::Service>::Error>;
type Response = <M::Value as svc::Service<Req>>::Response;
type Error = Error<M::Error, <M::Value as svc::Service<Req>>::Error>;
type Future = future::MapErr<
<M::Value as svc::Service>::Future,
fn(<M::Value as svc::Service>::Error) -> Self::Error,
<M::Value as svc::Service<Req>>::Future,
fn(<M::Value as svc::Service<Req>>::Error) -> Self::Error,
>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
@ -232,7 +229,7 @@ where
}
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: Req) -> Self::Future {
self.service
.as_mut()
.expect("poll_ready must be called first")

View File

@ -2,39 +2,43 @@ extern crate tower_balance;
extern crate tower_discover;
extern crate tower_h2_balance;
use http;
use std::marker::PhantomData;
use std::time::Duration;
use self::tower_discover::Discover;
use tower_h2::Body;
pub use self::tower_balance::{choose::PowerOfTwoChoices, load::WithPeakEwma, Balance};
pub use self::tower_h2_balance::{PendingUntilFirstData, PendingUntilFirstDataBody};
use http;
use svc;
use tower_h2::Body;
/// Configures a stack to resolve `T` typed targets to balance requests over
/// `M`-typed endpoint stacks.
#[derive(Clone, Debug)]
pub struct Layer {
#[derive(Debug)]
pub struct Layer<A, B> {
decay: Duration,
_marker: PhantomData<fn(A) -> B>,
}
/// Resolves `T` typed targets to balance requests over `M`-typed endpoint stacks.
#[derive(Clone, Debug)]
pub struct Stack<M> {
#[derive(Debug)]
pub struct Stack<M, A, B> {
decay: Duration,
inner: M,
_marker: PhantomData<fn(A) -> B>,
}
// === impl Layer ===
pub fn layer() -> Layer {
pub fn layer<A, B>() -> Layer<A, B> {
Layer {
decay: Layer::DEFAULT_DECAY,
_marker: PhantomData,
}
}
impl Layer {
impl Layer<(), ()> {
const DEFAULT_DECAY: Duration = Duration::from_secs(10);
// pub fn with_decay(self, decay: Duration) -> Self {
@ -45,31 +49,53 @@ impl Layer {
// }
}
impl<T, M, A, B> svc::Layer<T, T, M> for Layer
impl<A, B> Clone for Layer<A, B> {
fn clone(&self) -> Self {
Layer {
decay: self.decay,
_marker: PhantomData,
}
}
}
impl<T, M, A, B> svc::Layer<T, T, M> for Layer<A, B>
where
M: svc::Stack<T> + Clone,
M::Value: Discover<Request = http::Request<A>, Response = http::Response<B>>,
M::Value: Discover,
<M::Value as Discover>::Service: svc::Service<http::Request<A>, Response = http::Response<B>>,
A: Body,
B: Body,
{
type Value = <Stack<M> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error;
type Stack = Stack<M>;
type Value = <Stack<M, A, B> as svc::Stack<T>>::Value;
type Error = <Stack<M, A, B> as svc::Stack<T>>::Error;
type Stack = Stack<M, A, B>;
fn bind(&self, inner: M) -> Self::Stack {
Stack {
decay: self.decay,
inner,
_marker: PhantomData,
}
}
}
// === impl Stack ===
impl<T, M, A, B> svc::Stack<T> for Stack<M>
impl<M: Clone, A, B> Clone for Stack<M, A, B> {
fn clone(&self) -> Self {
Stack {
decay: self.decay,
inner: self.inner.clone(),
_marker: PhantomData,
}
}
}
impl<T, M, A, B> svc::Stack<T> for Stack<M, A, B>
where
M: svc::Stack<T> + Clone,
M::Value: Discover<Request = http::Request<A>, Response = http::Response<B>>,
M::Value: Discover,
<M::Value as Discover>::Service: svc::Service<http::Request<A>, Response = http::Response<B>>,
A: Body,
B: Body,
{

View File

@ -304,7 +304,7 @@ where
}
}
impl<C, E, B> svc::NewService for Client<C, E, B>
impl<C, E, B> svc::Service<()> for Client<C, E, B>
where
C: connect::Connect + Clone + Send + Sync + 'static,
C::Future: Send + 'static,
@ -315,20 +315,28 @@ where
B: tower_h2::Body + Send + 'static,
<B::Data as IntoBuf>::Buf: Send + 'static,
{
type Request = <Self::Service as svc::Service>::Request;
type Response = <Self::Service as svc::Service>::Response;
type Error = <Self::Service as svc::Service>::Error;
type InitError = tower_h2::client::ConnectError<C::Error>;
type Service = ClientService<C, E, B>;
type Response = ClientService<C, E, B>;
type Error = tower_h2::client::ConnectError<C::Error>;
type Future = ClientNewServiceFuture<C, E, B>;
fn new_service(&self) -> Self::Future {
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
match self.inner {
ClientInner::Http1(_) => {
Ok(().into())
},
ClientInner::Http2(ref mut h2) => {
h2.poll_ready()
},
}
}
fn call(&mut self, _target: ()) -> Self::Future {
let inner = match self.inner {
ClientInner::Http1(ref h1) => {
ClientNewServiceFutureInner::Http1(Some(h1.clone()))
},
ClientInner::Http2(ref h2) => {
ClientNewServiceFutureInner::Http2(h2.new_service())
ClientInner::Http2(ref mut h2) => {
ClientNewServiceFutureInner::Http2(h2.call(()))
},
};
ClientNewServiceFuture {
@ -370,7 +378,7 @@ where
// === impl ClientService ===
impl<C, E, B> svc::Service for ClientService<C, E, B>
impl<C, E, B> svc::Service<http::Request<B>> for ClientService<C, E, B>
where
C: connect::Connect + Send + Sync + 'static,
C::Connected: Send,
@ -381,7 +389,6 @@ where
B: tower_h2::Body + Send + 'static,
<B::Data as IntoBuf>::Buf: Send + 'static,
{
type Request = http::Request<B>;
type Response = http::Response<HttpBody>;
type Error = Error;
type Future = ClientServiceFuture;
@ -393,7 +400,7 @@ where
}
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: http::Request<B>) -> Self::Future {
debug!("client request: method={} uri={} version={:?} headers={:?}",
req.method(), req.uri(), req.version(), req.headers());
match self.inner {

View File

@ -232,7 +232,7 @@ impl<S, E> HyperServerSvc<S, E> {
impl<S, E, B> hyper::service::Service for HyperServerSvc<S, E>
where
S: svc::Service<
Request=http::Request<HttpBody>,
http::Request<HttpBody>,
Response=http::Response<B>,
>,
S::Error: Error + Send + Sync + 'static,
@ -312,13 +312,12 @@ where
// ==== impl HttpBodySvc ====
impl<S> svc::Service for HttpBodySvc<S>
impl<S> svc::Service<http::Request<tower_h2::RecvBody>> for HttpBodySvc<S>
where
S: svc::Service<
Request=http::Request<HttpBody>,
http::Request<HttpBody>,
>,
{
type Request = http::Request<tower_h2::RecvBody>;
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
@ -327,14 +326,14 @@ where
self.service.poll_ready()
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: http::Request<tower_h2::RecvBody>) -> Self::Future {
self.service.call(req.map(|b| HttpBody::Http2(b)))
}
}
impl<N> HttpBodyNewSvc<N>
where
N: svc::NewService<Request=http::Request<HttpBody>>,
N: svc::MakeService<(), http::Request<HttpBody>>,
{
pub(in proxy) fn new(new_service: N) -> Self {
HttpBodyNewSvc {
@ -343,20 +342,21 @@ where
}
}
impl<N> svc::NewService for HttpBodyNewSvc<N>
impl<N> svc::Service<()> for HttpBodyNewSvc<N>
where
N: svc::NewService<Request=http::Request<HttpBody>>,
N: svc::MakeService<(), http::Request<HttpBody>>,
{
type Request = http::Request<tower_h2::RecvBody>;
type Response = N::Response;
type Error = N::Error;
type Service = HttpBodySvc<N::Service>;
type InitError = N::InitError;
type Response = HttpBodySvc<N::Service>;
type Error = N::MakeError;
type Future = HttpBodyNewSvcFuture<N::Future>;
fn new_service(&self) -> Self::Future {
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.new_service.poll_ready()
}
fn call(&mut self, target: ()) -> Self::Future {
HttpBodyNewSvcFuture {
inner: self.new_service.new_service(),
inner: self.new_service.make_service(target),
}
}
}

View File

@ -35,13 +35,12 @@ where
Layer { header }
}
impl<H, T, M, B> svc::Layer<T, T, M> for Layer<H>
impl<H, T, M> svc::Layer<T, T, M> for Layer<H>
where
H: IntoHeaderName + Clone,
T: Clone + Send + Sync + 'static,
HeaderValue: for<'t> From<&'t T>,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<B>>,
{
type Value = <Stack<H, M> as svc::Stack<T>>::Value;
type Error = <Stack<H, M> as svc::Stack<T>>::Error;
@ -57,13 +56,12 @@ where
// === impl Stack ===
impl<H, T, M, B> svc::Stack<T> for Stack<H, M>
impl<H, T, M> svc::Stack<T> for Stack<H, M>
where
H: IntoHeaderName + Clone,
T: Clone + Send + Sync + 'static,
HeaderValue: for<'t> From<&'t T>,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<B>>,
{
type Value = Service<H, M::Value>;
type Error = M::Error;
@ -78,12 +76,11 @@ where
// === impl Service ===
impl<H, S, B> svc::Service for Service<H, S>
impl<H, S, B> svc::Service<http::Request<B>> for Service<H, S>
where
H: IntoHeaderName + Clone,
S: svc::Service<Request = http::Request<B>>,
S: svc::Service<http::Request<B>>,
{
type Request = S::Request;
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
@ -92,7 +89,7 @@ where
self.inner.poll_ready()
}
fn call(&mut self, mut req: Self::Request) -> Self::Future {
fn call(&mut self, mut req: http::Request<B>) -> Self::Future {
req.headers_mut().insert(self.header.clone(), self.value.clone());
self.inner.call(req)
}

View File

@ -25,11 +25,10 @@ pub fn layer() -> Layer {
Layer
}
impl<T, M, B> svc::Layer<T, T, M> for Layer
impl<T, M> svc::Layer<T, T, M> for Layer
where
T: Clone + Send + Sync + 'static,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<B>>,
{
type Value = <Stack<M> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error;
@ -42,11 +41,10 @@ where
// === impl Stack ===
impl<T, M, B> svc::Stack<T> for Stack<M>
impl<T, M> svc::Stack<T> for Stack<M>
where
T: Clone + Send + Sync + 'static,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<B>>,
{
type Value = Service<T, M::Value>;
type Error = M::Error;
@ -60,12 +58,11 @@ where
// === impl Service ===
impl<T, S, B> svc::Service for Service<T, S>
impl<T, S, B> svc::Service<http::Request<B>> for Service<T, S>
where
T: Clone + Send + Sync + 'static,
S: svc::Service<Request = http::Request<B>>,
S: svc::Service<http::Request<B>>,
{
type Request = S::Request;
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
@ -74,7 +71,7 @@ where
self.inner.poll_ready()
}
fn call(&mut self, mut req: Self::Request) -> Self::Future {
fn call(&mut self, mut req: http::Request<B>) -> Self::Future {
req.extensions_mut().insert(self.target.clone());
self.inner.call(req)
}

View File

@ -74,7 +74,7 @@ pub struct Stack<M> {
}
#[derive(Clone, Debug)]
pub struct Service<C, S: svc::Service> {
pub struct Service<C, S> {
classify: C,
inner: S,
}
@ -83,11 +83,10 @@ pub fn layer() -> Layer {
Layer()
}
impl<T, M, A, B> svc::Layer<T, T, M> for Layer
impl<T, M> svc::Layer<T, T, M> for Layer
where
T: CanClassify,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
{
type Value = <Stack<M> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error;
@ -98,11 +97,10 @@ where
}
}
impl<T, M, A, B> svc::Stack<T> for Stack<M>
impl<T, M> svc::Stack<T> for Stack<M>
where
T: CanClassify,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
{
type Value = Service<T::Classify, M::Value>;
type Error = M::Error;
@ -114,12 +112,11 @@ where
}
}
impl<C, S, A, B> svc::Service for Service<C, S>
impl<C, S, A, B> svc::Service<http::Request<A>> for Service<C, S>
where
C: Classify,
S: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
S: svc::Service<http::Request<A>, Response = http::Response<B>>,
{
type Request = S::Request;
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;

View File

@ -8,6 +8,7 @@ use std::sync::{Arc, Mutex};
use std::time::Instant;
use tokio_timer::clock;
use tower_h2;
use tower_grpc;
use super::classify::{ClassifyEos, ClassifyResponse};
use super::{ClassMetrics, Metrics, Registry, StatusMetrics};
@ -42,7 +43,6 @@ where
#[derive(Debug)]
pub struct Service<S, C>
where
S: svc::Service,
C: ClassifyResponse<Error = h2::Error> + Clone,
C::Class: Hash + Eq,
{
@ -51,16 +51,15 @@ where
_p: PhantomData<fn() -> C>,
}
pub struct ResponseFuture<S, C>
pub struct ResponseFuture<F, C>
where
S: svc::Service,
C: ClassifyResponse<Error = h2::Error>,
C::Class: Hash + Eq,
{
classify: Option<C>,
metrics: Option<Arc<Mutex<Metrics<C::Class>>>>,
stream_open_at: Instant,
inner: S::Future,
inner: F,
}
#[derive(Debug)]
@ -116,17 +115,11 @@ where
}
}
impl<T, M, K, C, A, B> svc::Layer<T, T, M> for Layer<K, C>
impl<T, M, K, C> svc::Layer<T, T, M> for Layer<K, C>
where
T: Clone + Debug,
K: Clone + Hash + Eq + From<T>,
M: svc::Stack<T>,
M::Value: svc::Service<
Request = http::Request<RequestBody<A, C::Class>>,
Response = http::Response<B>,
>,
A: tower_h2::Body,
B: tower_h2::Body,
C: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static,
C::Class: Hash + Eq,
{
@ -161,17 +154,11 @@ where
}
}
impl<T, M, K, C, A, B> svc::Stack<T> for Stack<M, K, C>
impl<T, M, K, C> svc::Stack<T> for Stack<M, K, C>
where
T: Clone + Debug,
K: Clone + Hash + Eq + From<T>,
M: svc::Stack<T>,
M::Value: svc::Service<
Request = http::Request<RequestBody<A, C::Class>>,
Response = http::Response<B>,
>,
A: tower_h2::Body,
B: tower_h2::Body,
C: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static,
C::Class: Hash + Eq,
{
@ -205,7 +192,7 @@ where
impl<S, C> Clone for Service<S, C>
where
S: svc::Service + Clone,
S: Clone,
C: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static,
C::Class: Hash + Eq,
{
@ -218,10 +205,10 @@ where
}
}
impl<C, S, A, B> svc::Service for Service<S, C>
impl<C, S, A, B> svc::Service<http::Request<A>> for Service<S, C>
where
S: svc::Service<
Request = http::Request<RequestBody<A, C::Class>>,
http::Request<RequestBody<A, C::Class>>,
Response = http::Response<B>,
>,
A: tower_h2::Body,
@ -229,16 +216,15 @@ where
C: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static,
C::Class: Hash + Eq,
{
type Request = http::Request<A>;
type Response = http::Response<ResponseBody<B, C::ClassifyEos>>;
type Error = S::Error;
type Future = ResponseFuture<S, C>;
type Future = ResponseFuture<S::Future, C>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.inner.poll_ready()
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: http::Request<A>) -> Self::Future {
let mut req_metrics = self.metrics.clone();
if req.body().is_end_stream() {
@ -271,15 +257,15 @@ where
}
}
impl<C, S, B> Future for ResponseFuture<S, C>
impl<C, F, B> Future for ResponseFuture<F, C>
where
S: svc::Service<Response = http::Response<B>>,
F: Future<Item = http::Response<B>>,
B: tower_h2::Body,
C: ClassifyResponse<Error = h2::Error> + Send + Sync + 'static,
C::Class: Hash + Eq,
{
type Item = http::Response<ResponseBody<B, C::ClassifyEos>>;
type Error = S::Error;
type Error = F::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let rsp = try_ready!(self.inner.poll());
@ -333,6 +319,26 @@ where
}
}
impl<B, C> tower_grpc::Body for RequestBody<B, C>
where
B: tower_h2::Body,
C: Hash + Eq,
{
type Data = B::Data;
fn is_end_stream(&self) -> bool {
::tower_h2::Body::is_end_stream(self)
}
fn poll_data(&mut self) -> Poll<Option<Self::Data>, tower_grpc::Error> {
::tower_h2::Body::poll_data(self).map_err(From::from)
}
fn poll_metadata(&mut self) -> Poll<Option<http::HeaderMap>, tower_grpc::Error> {
::tower_h2::Body::poll_trailers(self).map_err(From::from)
}
}
impl<B, C> Default for ResponseBody<B, C>
where
B: tower_h2::Body + Default,
@ -448,6 +454,27 @@ where
}
}
impl<B, C> tower_grpc::Body for ResponseBody<B, C>
where
B: tower_h2::Body,
C: ClassifyEos<Error = h2::Error>,
C::Class: Hash + Eq,
{
type Data = B::Data;
fn is_end_stream(&self) -> bool {
::tower_h2::Body::is_end_stream(self)
}
fn poll_data(&mut self) -> Poll<Option<Self::Data>, tower_grpc::Error> {
::tower_h2::Body::poll_data(self).map_err(From::from)
}
fn poll_metadata(&mut self) -> Poll<Option<http::HeaderMap>, tower_grpc::Error> {
::tower_h2::Body::poll_trailers(self).map_err(From::from)
}
}
impl<B, C> Drop for ResponseBody<B, C>
where
B: tower_h2::Body,

View File

@ -27,11 +27,10 @@ pub fn layer() -> Layer {
Layer()
}
impl<T, B, M> svc::Layer<T, T, M> for Layer
impl<T, M> svc::Layer<T, T, M> for Layer
where
T: ShouldNormalizeUri,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<B>>,
{
type Value = <Stack<M> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error;
@ -44,11 +43,10 @@ where
// === impl Stack ===
impl<T, B, M> svc::Stack<T> for Stack<M>
impl<T, M> svc::Stack<T> for Stack<M>
where
T: ShouldNormalizeUri,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<B>>,
{
type Value = svc::Either<Service<M::Value>, M::Value>;
type Error = M::Error;
@ -65,11 +63,10 @@ where
// === impl Service ===
impl<S, B> svc::Service for Service<S>
impl<S, B> svc::Service<http::Request<B>> for Service<S>
where
S: svc::Service<Request = http::Request<B>>,
S: svc::Service<http::Request<B>>,
{
type Request = S::Request;
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
@ -78,7 +75,7 @@ where
self.inner.poll_ready()
}
fn call(&mut self, mut request: S::Request) -> Self::Future {
fn call(&mut self, mut request: http::Request<B>) -> Self::Future {
debug_assert!(
request.version() != http::Version::HTTP_2,
"normalize_uri must only be applied to HTTP/1"

View File

@ -22,20 +22,19 @@ pub struct Downgrade<S> {
// ==== impl Upgrade =====
impl<S, A, B> From<S> for Upgrade<S>
impl<S> Upgrade<S> {
pub fn new<A, B>(inner: S) -> Self
where
S: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
S: svc::Service<http::Request<A>, Response = http::Response<B>>,
{
fn from(inner: S) -> Self {
Self { inner }
}
}
impl<S, A, B> svc::Service for Upgrade<S>
impl<S, A, B> svc::Service<http::Request<A>> for Upgrade<S>
where
S: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
S: svc::Service<http::Request<A>, Response = http::Response<B>>,
{
type Request = S::Request;
type Response = S::Response;
type Error = S::Error;
type Future = future::Map<
@ -47,7 +46,7 @@ where
self.inner.poll_ready()
}
fn call(&mut self, mut req: Self::Request) -> Self::Future {
fn call(&mut self, mut req: http::Request<A>) -> Self::Future {
if req.version() == http::Version::HTTP_2 || h1::wants_upgrade(&req) {
// Just passing through...
return self.inner.call(req).map(|res| res)
@ -106,21 +105,20 @@ where
// ===== impl Downgrade =====
impl<S, A, B> From<S> for Downgrade<S>
impl<S> Downgrade<S> {
pub fn new<A, B>(inner: S) -> Self
where
S: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
S: svc::Service<http::Request<A>, Response = http::Response<B>>,
{
fn from(inner: S) -> Self {
Self { inner }
}
}
impl<S, A, B> svc::Service for Downgrade<S>
impl<S, A, B> svc::Service<http::Request<A>> for Downgrade<S>
where
S: svc::Service<Request = http::Request<A>, Response = http::Response<B>>,
S: svc::Service<http::Request<A>, Response = http::Response<B>>,
{
type Request = S::Request;
type Response = S::Response;
type Error = S::Error;
type Future = future::Map<
@ -132,7 +130,7 @@ where
self.inner.poll_ready()
}
fn call(&mut self, mut req: Self::Request) -> Self::Future {
fn call(&mut self, mut req: http::Request<A>) -> Self::Future {
let mut upgrade_response = false;
if req.version() == http::Version::HTTP_2 {

View File

@ -189,7 +189,6 @@ pub mod router {
<T as WithRoute>::Output,
svc::shared::Stack<M::Value>,
> + Clone,
R::Value: svc::Service,
{
Layer {
suffixes,
@ -228,7 +227,6 @@ pub mod router {
where
T: WithRoute,
R: svc::Stack<T::Output>,
R::Value: svc::Service,
{
target: T,
stack: R,
@ -259,7 +257,6 @@ pub mod router {
<T as WithRoute>::Output,
svc::shared::Stack<M::Value>,
> + Clone,
R::Value: svc::Service,
{
type Value = <Stack<G, M, R> as svc::Stack<T>>::Value;
type Error = <Stack<G, M, R> as svc::Stack<T>>::Error;
@ -287,7 +284,6 @@ pub mod router {
<T as WithRoute>::Output,
svc::shared::Stack<M::Value>,
> + Clone,
R::Value: svc::Service,
{
type Value = Service<G::Stream, T, R::Stack>;
type Error = Error<M::Error, R::Error>;
@ -332,7 +328,6 @@ pub mod router {
G: Stream<Item = Routes, Error = super::Error>,
T: WithRoute + Clone,
R: svc::Stack<T::Output> + Clone,
R::Value: svc::Service,
{
fn update_routes(&mut self, mut routes: Routes) {
self.routes = Vec::with_capacity(routes.len());
@ -352,17 +347,16 @@ pub mod router {
}
}
impl<G, T, R, B> svc::Service for Service<G, T, R>
impl<G, T, R, B> svc::Service<http::Request<B>> for Service<G, T, R>
where
G: Stream<Item = Routes, Error = super::Error>,
T: WithRoute + Clone,
R: svc::Stack<T::Output> + Clone,
R::Value: svc::Service<Request = http::Request<B>>,
R::Value: svc::Service<http::Request<B>>,
{
type Request = <R::Value as svc::Service>::Request;
type Response = <R::Value as svc::Service>::Response;
type Error = <R::Value as svc::Service>::Error;
type Future = <R::Value as svc::Service>::Future;
type Response = <R::Value as svc::Service<http::Request<B>>>::Response;
type Error = <R::Value as svc::Service<http::Request<B>>>::Error;
type Future = <R::Value as svc::Service<http::Request<B>>>::Future;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
while let Some(Async::Ready(Some(routes))) = self.poll_route_stream() {
@ -372,7 +366,7 @@ pub mod router {
Ok(Async::Ready(()))
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: http::Request<B>) -> Self::Future {
for (ref condition, ref mut service) in &mut self.routes {
if condition.is_match(&req) {
trace!("using configured route: {:?}", condition);

View File

@ -43,7 +43,7 @@ pub struct Service<Req, Rec, Stk>
where
Rec: Recognize<Req>,
Stk: svc::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>,
Stk::Value: svc::Service<Req>,
{
inner: Router<Req, Rec, Stk>,
}
@ -88,8 +88,8 @@ impl<Req, Rec, Stk, B> svc::Layer<Config, Rec::Target, Stk> for Layer<Req, Rec>
where
Rec: Recognize<Req> + Clone + Send + Sync + 'static,
Stk: svc::Stack<Rec::Target> + Clone + Send + Sync + 'static,
Stk::Value: svc::Service<Request = Req, Response = http::Response<B>>,
<Stk::Value as svc::Service>::Error: error::Error,
Stk::Value: svc::Service<Req, Response = http::Response<B>>,
<Stk::Value as svc::Service<Req>>::Error: error::Error,
Stk::Error: fmt::Debug,
B: Default + Send + 'static,
{
@ -112,8 +112,8 @@ impl<Req, Rec, Stk, B> svc::Stack<Config> for Stack<Req, Rec, Stk>
where
Rec: Recognize<Req> + Clone + Send + Sync + 'static,
Stk: svc::Stack<Rec::Target> + Clone + Send + Sync + 'static,
Stk::Value: svc::Service<Request = Req, Response = http::Response<B>>,
<Stk::Value as svc::Service>::Error: error::Error,
Stk::Value: svc::Service<Req, Response = http::Response<B>>,
<Stk::Value as svc::Service<Req>>::Error: error::Error,
Stk::Error: fmt::Debug,
B: Default + Send + 'static,
{
@ -160,19 +160,18 @@ where
// === impl Service ===
impl<Req, Rec, Stk, B> svc::Service for Service<Req, Rec, Stk>
impl<Req, Rec, Stk, B> svc::Service<Req> for Service<Req, Rec, Stk>
where
Rec: Recognize<Req> + Send + Sync + 'static,
Stk: svc::Stack<Rec::Target> + Send + Sync + 'static,
Stk::Value: svc::Service<Request = Req, Response = http::Response<B>>,
<Stk::Value as svc::Service>::Error: error::Error,
Stk::Value: svc::Service<Req, Response = http::Response<B>>,
<Stk::Value as svc::Service<Req>>::Error: error::Error,
Stk::Error: fmt::Debug,
B: Default + Send + 'static,
{
type Request = <Router<Req, Rec, Stk> as svc::Service>::Request;
type Response = <Router<Req, Rec, Stk> as svc::Service>::Response;
type Response = <Router<Req, Rec, Stk> as svc::Service<Req>>::Response;
type Error = h2::Error;
type Future = ResponseFuture<<Router<Req, Rec, Stk> as svc::Service>::Future>;
type Future = ResponseFuture<<Router<Req, Rec, Stk> as svc::Service<Req>>::Future>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.inner.poll_ready().map_err(|e| {
@ -181,7 +180,7 @@ where
})
}
fn call(&mut self, request: Self::Request) -> Self::Future {
fn call(&mut self, request: Req) -> Self::Future {
trace!("routing...");
let inner = self.inner.call(request);
ResponseFuture { inner }
@ -192,7 +191,7 @@ impl<Req, Rec, Stk> Clone for Service<Req, Rec, Stk>
where
Rec: Recognize<Req>,
Stk: svc::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>,
Stk::Value: svc::Service<Req>,
Router<Req, Rec, Stk>: Clone,
{
fn clone(&self) -> Self {

View File

@ -95,16 +95,16 @@ pub mod router {
fn connect(&self) -> connect::Target;
}
#[derive(Clone, Debug)]
pub struct Layer<T>(PhantomData<T>);
#[derive(Debug)]
pub struct Layer<T, B>(PhantomData<(T, fn(B))>);
#[derive(Clone, Debug)]
pub struct Stack<M>(M);
#[derive(Debug)]
pub struct Stack<B, M>(M, PhantomData<fn(B)>);
pub struct Service<B, M>
where
M: svc::Stack<Config>,
M::Value: svc::Service<Request = http::Request<B>>,
M::Value: svc::Service<http::Request<B>>,
{
router: Router<B, M>,
}
@ -112,9 +112,9 @@ pub mod router {
pub struct ResponseFuture<B, M>
where
M: svc::Stack<Config>,
M::Value: svc::Service<Request = http::Request<B>>,
M::Value: svc::Service<http::Request<B>>,
{
inner: <Router<B, M> as svc::Service>::Future
inner: <Router<B, M> as svc::Service<http::Request<B>>>::Future
}
#[derive(Debug)]
@ -127,30 +127,42 @@ pub mod router {
type Router<B, M> = rt::Router<http::Request<B>, Recognize, M>;
pub fn layer<T: HasConnect>() -> Layer<T> {
pub fn layer<T: HasConnect, B>() -> Layer<T, B> {
Layer(PhantomData)
}
impl<B, T, M> svc::Layer<T, Config, M> for Layer<T>
impl<T, B> Clone for Layer<T, B> {
fn clone(&self) -> Self {
Layer(PhantomData)
}
}
impl<B, T, M> svc::Layer<T, Config, M> for Layer<T, B>
where
T: HasConnect,
M: svc::Stack<Config> + Clone,
M::Value: svc::Service<Request = http::Request<B>>,
M::Value: svc::Service<http::Request<B>>,
{
type Value = <Stack<M> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error;
type Stack = Stack<M>;
type Value = <Stack<B, M> as svc::Stack<T>>::Value;
type Error = <Stack<B, M> as svc::Stack<T>>::Error;
type Stack = Stack<B, M>;
fn bind(&self, inner: M) -> Self::Stack {
Stack(inner)
Stack(inner, PhantomData)
}
}
impl<B, T, M> svc::Stack<T> for Stack<M>
impl<B, M: Clone> Clone for Stack<B, M> {
fn clone(&self) -> Self {
Stack(self.0.clone(), PhantomData)
}
}
impl<B, T, M> svc::Stack<T> for Stack<B, M>
where
T: HasConnect,
M: svc::Stack<Config> + Clone,
M::Value: svc::Service<Request = http::Request<B>>,
M::Value: svc::Service<http::Request<B>>,
{
type Value = Service<B, M>;
type Error = M::Error;
@ -179,14 +191,13 @@ pub mod router {
}
}
impl<B, M> svc::Service for Service<B, M>
impl<B, M> svc::Service<http::Request<B>> for Service<B, M>
where
M: svc::Stack<Config>,
M::Value: svc::Service<Request = http::Request<B>>,
M::Value: svc::Service<http::Request<B>>,
{
type Request = <Router<B, M> as svc::Service>::Request;
type Response = <Router<B, M> as svc::Service>::Response;
type Error = Error<<M::Value as svc::Service>::Error, M::Error>;
type Response = <Router<B, M> as svc::Service<http::Request<B>>>::Response;
type Error = Error<<M::Value as svc::Service<http::Request<B>>>::Error, M::Error>;
type Future = ResponseFuture<B, M>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
@ -200,7 +211,7 @@ pub mod router {
}
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: http::Request<B>) -> Self::Future {
ResponseFuture { inner: self.router.call(req) }
}
}
@ -208,10 +219,10 @@ pub mod router {
impl<B, M> Future for ResponseFuture<B, M>
where
M: svc::Stack<Config>,
M::Value: svc::Service<Request = http::Request<B>>,
M::Value: svc::Service<http::Request<B>>,
{
type Item = <Router<B, M> as svc::Service>::Response;
type Error = Error<<M::Value as svc::Service>::Error, M::Error>;
type Item = <Router<B, M> as svc::Service<http::Request<B>>>::Response;
type Error = Error<<M::Value as svc::Service<http::Request<B>>>::Error, M::Error>;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match self.inner.poll() {

View File

@ -1,59 +1,80 @@
extern crate tower_in_flight_limit;
use std::fmt;
use std::{fmt, marker::PhantomData};
pub use self::tower_in_flight_limit::InFlightLimit;
use svc;
/// Wraps `Service` stacks with an `InFlightLimit`.
#[derive(Clone, Debug)]
pub struct Layer {
#[derive(Debug)]
pub struct Layer<Req> {
max_in_flight: usize,
_marker: PhantomData<fn(Req)>,
}
/// Produces `Services` wrapped with an `InFlightLimit`.
#[derive(Clone, Debug)]
pub struct Stack<M> {
max_in_flight: usize,
#[derive(Debug)]
pub struct Stack<M, Req> {
inner: M,
max_in_flight: usize,
_marker: PhantomData<fn(Req)>,
}
// === impl Layer ===
pub fn layer(max_in_flight: usize) -> Layer {
Layer { max_in_flight }
pub fn layer<Req>(max_in_flight: usize) -> Layer<Req> {
Layer {
max_in_flight,
_marker: PhantomData,
}
}
impl<T, M> svc::Layer<T, T, M> for Layer
impl<Req> Clone for Layer<Req> {
fn clone(&self) -> Self {
Layer {
max_in_flight: self.max_in_flight,
_marker: PhantomData,
}
}
}
impl<T, M, Req> svc::Layer<T, T, M> for Layer<Req>
where
T: fmt::Display + Clone + Send + Sync + 'static,
M: svc::Stack<T>,
M::Value: svc::Service + Send + 'static,
<M::Value as svc::Service>::Request: Send,
<M::Value as svc::Service>::Future: Send,
M::Value: svc::Service<Req>,
{
type Value = <Stack<M> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error;
type Stack = Stack<M>;
type Value = <Stack<M, Req> as svc::Stack<T>>::Value;
type Error = <Stack<M, Req> as svc::Stack<T>>::Error;
type Stack = Stack<M, Req>;
fn bind(&self, inner: M) -> Self::Stack {
Stack {
inner,
max_in_flight: self.max_in_flight,
_marker: PhantomData,
}
}
}
// === impl Stack ===
impl<T, M> svc::Stack<T> for Stack<M>
impl<M: Clone, Req> Clone for Stack<M, Req> {
fn clone(&self) -> Self {
Stack {
inner: self.inner.clone(),
max_in_flight: self.max_in_flight,
_marker: PhantomData,
}
}
}
impl<T, M, Req> svc::Stack<T> for Stack<M, Req>
where
T: fmt::Display + Clone + Send + Sync + 'static,
M: svc::Stack<T>,
M::Value: svc::Service + Send + 'static,
<M::Value as svc::Service>::Request: Send,
<M::Value as svc::Service>::Future: Send,
M::Value: svc::Service<Req>,
{
type Value = InFlightLimit<M::Value>;
type Error = M::Error;

View File

@ -1,5 +1,6 @@
extern crate tower_reconnect;
use futures::{task, Async, Future, Poll};
use std::fmt;
use std::time::Duration;
@ -26,9 +27,9 @@ pub struct Stack<M> {
pub struct Service<T, N>
where
T: fmt::Debug,
N: svc::NewService,
N: svc::Service<()>,
{
inner: Reconnect<N>,
inner: Reconnect<N, ()>,
/// The target, used for debug logging.
target: T,
@ -48,8 +49,8 @@ enum Backoff {
Fixed(Duration),
}
pub struct ResponseFuture<N: svc::NewService> {
inner: <Reconnect<N> as svc::Service>::Future,
pub struct ResponseFuture<F> {
inner: F,
}
// === impl Layer ===
@ -73,7 +74,7 @@ impl<T, M> svc::Layer<T, T, M> for Layer
where
T: Clone + fmt::Debug,
M: svc::Stack<T>,
M::Value: svc::NewService,
M::Value: svc::Service<()>,
{
type Value = <Stack<M> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error;
@ -93,7 +94,7 @@ impl<T, M> svc::Stack<T> for Stack<M>
where
T: Clone + fmt::Debug,
M: svc::Stack<T>,
M::Value: svc::NewService,
M::Value: svc::Service<()>,
{
type Value = Service<T, M::Value>;
type Error = M::Error;
@ -101,7 +102,7 @@ where
fn make(&self, target: &T) -> Result<Self::Value, Self::Error> {
let new_service = self.inner.make(target)?;
Ok(Service {
inner: Reconnect::new(new_service),
inner: Reconnect::new(new_service, ()),
target: target.clone(),
backoff: self.backoff.clone(),
active_backoff: None,
@ -115,12 +116,12 @@ where
#[cfg(test)]
impl<N> Service<&'static str, N>
where
N: svc::NewService,
N::InitError: fmt::Display,
N: svc::Service<()>,
N::Error: fmt::Display,
{
fn for_test(new_service: N) -> Self {
Self {
inner: Reconnect::new(new_service),
inner: Reconnect::new(new_service, ()),
target: "test",
backoff: Backoff::None,
active_backoff: None,
@ -136,16 +137,16 @@ where
}
}
impl<T, N> svc::Service for Service<T, N>
impl<T, N, S, Req> svc::Service<Req> for Service<T, N>
where
T: fmt::Debug,
N: svc::NewService,
N::InitError: fmt::Display,
N: svc::Service<(), Response=S>,
N::Error: fmt::Display,
S: svc::Service<Req>,
{
type Request = N::Request;
type Response = N::Response;
type Error = N::Error;
type Future = ResponseFuture<N>;
type Response = S::Response;
type Error = S::Error;
type Future = ResponseFuture<<Reconnect<N, ()> as svc::Service<Req>>::Future>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
match self.backoff {
@ -171,7 +172,7 @@ where
Ok(ready)
}
Err(Error::Inner(err)) => {
Err(Error::Service(err)) => {
self.mute_connect_error_log = false;
Err(err)
}
@ -214,14 +215,18 @@ where
}
}
fn call(&mut self, request: Self::Request) -> Self::Future {
fn call(&mut self, request: Req) -> Self::Future {
ResponseFuture {
inner: self.inner.call(request),
}
}
}
impl<T: fmt::Debug, N: svc::NewService> fmt::Debug for Service<T, N> {
impl<T, N> fmt::Debug for Service<T, N>
where
T: fmt::Debug,
N: svc::Service<()>,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Reconnect")
.field("target", &self.target)
@ -229,13 +234,16 @@ impl<T: fmt::Debug, N: svc::NewService> fmt::Debug for Service<T, N> {
}
}
impl<N: svc::NewService> Future for ResponseFuture<N> {
type Item = N::Response;
type Error = N::Error;
impl<F, E, Cant> Future for ResponseFuture<F>
where
F: Future<Error = Error<E, Cant>>,
{
type Item = F::Item;
type Error = E;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
self.inner.poll().map_err(|e| match e {
Error::Inner(err) => err,
Error::Service(err) => err,
_ => unreachable!("response future must fail with inner error"),
})
}
@ -263,23 +271,23 @@ mod tests {
#[derive(Debug)]
struct InitErr {}
impl svc::NewService for NewService {
type Request = ();
type Response = ();
type Error = ();
type Service = Service;
type InitError = InitErr;
impl svc::Service<()> for NewService {
type Response = Service;
type Error = InitErr;
type Future = InitFuture;
fn new_service(&self) -> Self::Future {
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(().into())
}
fn call(&mut self, _: ()) -> Self::Future {
InitFuture {
should_fail: self.fails.fetch_sub(1, Relaxed) > 0,
}
}
}
impl svc::Service for Service {
type Request = ();
impl svc::Service<()> for Service {
type Response = ();
type Error = ();
type Future = future::FutureResult<(), ()>;

View File

@ -65,7 +65,6 @@ where
R: Resolve<T> + Clone,
R::Endpoint: fmt::Debug,
M: svc::Stack<R::Endpoint> + Clone,
M::Value: svc::Service,
{
type Value = <Stack<R, M> as svc::Stack<T>>::Value;
type Error = <Stack<R, M> as svc::Stack<T>>::Error;
@ -86,7 +85,6 @@ where
R: Resolve<T>,
R::Endpoint: fmt::Debug,
M: svc::Stack<R::Endpoint> + Clone,
M::Value: svc::Service,
{
type Value = Discover<R::Resolution, M>;
type Error = M::Error;
@ -107,16 +105,12 @@ where
R: Resolution,
R::Endpoint: fmt::Debug,
M: svc::Stack<R::Endpoint>,
M::Value: svc::Service,
{
type Key = SocketAddr;
type Request = <M::Value as svc::Service>::Request;
type Response = <M::Value as svc::Service>::Response;
type Error = <M::Value as svc::Service>::Error;
type Service = M::Value;
type DiscoverError = Error<R::Error, M::Error>;
type Error = Error<R::Error, M::Error>;
fn poll(&mut self) -> Poll<Change<Self::Key, Self::Service>, Self::DiscoverError> {
fn poll(&mut self) -> Poll<Change<Self::Key, Self::Service>, Self::Error> {
loop {
let up = try_ready!(self.resolution.poll().map_err(Error::Resolve));
trace!("watch: {:?}", up);

View File

@ -10,7 +10,7 @@ use tower_h2;
use Conditional;
use drain;
use never::Never;
use svc::{Stack, Service, stack::StackNewService};
use svc::{Stack, Service, stack::StackMakeService};
use transport::{connect, tls, Connection, GetOriginalDst, Peek};
use proxy::http::glue::{HttpBody, HttpBodyNewSvc, HyperServerSvc};
use proxy::protocol::Protocol;
@ -53,7 +53,7 @@ where
// Prepares a route for each accepted HTTP connection.
R: Stack<Source, Error = Never> + Clone,
R::Value: Service<
Request = http::Request<HttpBody>,
http::Request<HttpBody>,
Response = http::Response<B>,
>,
B: tower_h2::Body,
@ -193,12 +193,12 @@ where
<C::Value as connect::Connect>::Error: fmt::Debug + 'static,
R: Stack<Source, Error = Never> + Clone,
R::Value: Service<
Request = http::Request<HttpBody>,
http::Request<HttpBody>,
Response = http::Response<B>,
>,
R::Value: 'static,
<R::Value as Service>::Error: error::Error + Send + Sync + 'static,
<R::Value as Service>::Future: Send + 'static,
<R::Value as Service<http::Request<HttpBody>>>::Error: error::Error + Send + Sync + 'static,
<R::Value as Service<http::Request<HttpBody>>>::Future: Send + 'static,
B: tower_h2::Body + Default + Send + 'static,
B::Data: Send,
<B::Data as ::bytes::IntoBuf>::Buf: Send,
@ -327,8 +327,8 @@ where
}),
Protocol::Http2 => Either::B({
trace!("detected HTTP/2");
let new_service = StackNewService::new(route, source.clone());
let h2 = tower_h2::Server::new(
let new_service = StackMakeService::new(route, source.clone());
let mut h2 = tower_h2::Server::new(
HttpBodyNewSvc::new(new_service),
h2_settings,
log_clone.executor(),

View File

@ -1,7 +1,7 @@
pub extern crate linkerd2_stack as stack;
extern crate tower_service;
pub use self::tower_service::{NewService, Service};
pub use self::tower_service::{MakeService, Service};
pub use self::stack::{
shared,

View File

@ -37,10 +37,7 @@ where
/// A middleware that records HTTP taps.
#[derive(Clone, Debug)]
pub struct Service<S>
where
S: svc::Service,
{
pub struct Service<S> {
endpoint: event::Endpoint,
next_id: NextId,
taps: Arc<Mutex<Taps>>,
@ -48,11 +45,8 @@ where
}
#[derive(Debug, Clone)]
pub struct ResponseFuture<S>
where
S: svc::Service,
{
inner: S::Future,
pub struct ResponseFuture<F> {
inner: F,
meta: Option<event::Request>,
taps: Option<Arc<Mutex<Taps>>>,
request_open_at: Instant,
@ -86,8 +80,8 @@ pub fn layer<T, M, A, B>(next_id: NextId, taps: Arc<Mutex<Taps>>) -> Layer<T, M>
where
T: Clone + Into<event::Endpoint>,
M: svc::Stack<T>,
M::Value: svc::Service<Request = http::Request<RequestBody<A>>, Response = http::Response<B>>,
<M::Value as svc::Service>::Error: HasH2Reason,
M::Value: svc::Service<http::Request<RequestBody<A>>, Response = http::Response<B>>,
<M::Value as svc::Service<http::Request<RequestBody<A>>>>::Error: HasH2Reason,
A: Body,
B: Body,
{
@ -98,17 +92,10 @@ where
}
}
impl<T, M, A, B> svc::Layer<T, T, M> for Layer<T, M>
impl<T, M> svc::Layer<T, T, M> for Layer<T, M>
where
T: Clone + Into<event::Endpoint>,
M: svc::Stack<T>,
M::Value: svc::Service<
Request = http::Request<RequestBody<A>>,
Response = http::Response<B>,
>,
<M::Value as svc::Service>::Error: HasH2Reason,
A: Body,
B: Body,
{
type Value = <Stack<T, M> as svc::Stack<T>>::Value;
type Error = M::Error;
@ -126,17 +113,10 @@ where
// === Stack ===
impl<T, M, A, B> svc::Stack<T> for Stack<T, M>
impl<T, M> svc::Stack<T> for Stack<T, M>
where
T: Clone + Into<event::Endpoint>,
M: svc::Stack<T>,
M::Value: svc::Service<
Request = http::Request<RequestBody<A>>,
Response = http::Response<B>,
>,
<M::Value as svc::Service>::Error: HasH2Reason,
A: Body,
B: Body,
{
type Value = Service<M::Value>;
type Error = M::Error;
@ -154,26 +134,25 @@ where
// === Service ===
impl<S, A, B> svc::Service for Service<S>
impl<S, A, B> svc::Service<http::Request<A>> for Service<S>
where
S: svc::Service<
Request = http::Request<RequestBody<A>>,
http::Request<RequestBody<A>>,
Response = http::Response<B>,
>,
S::Error: HasH2Reason,
A: Body,
B: Body,
{
type Request = http::Request<A>;
type Response = http::Response<ResponseBody<B>>;
type Error = S::Error;
type Future = ResponseFuture<S>;
type Future = ResponseFuture<S::Future>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.inner.poll_ready()
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: http::Request<A>) -> Self::Future {
let request_open_at = clock::now();
// Only tap a request iff a `Source` is known.
@ -222,14 +201,14 @@ where
}
}
impl<S, B> Future for ResponseFuture<S>
impl<F, B> Future for ResponseFuture<F>
where
B: Body,
S: svc::Service<Response = http::Response<B>>,
S::Error: HasH2Reason,
F: Future<Item = http::Response<B>>,
F::Error: HasH2Reason,
{
type Item = http::Response<ResponseBody<B>>;
type Error = S::Error;
type Error = F::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let rsp = try_ready!(self.inner.poll().map_err(|e| self.tap_err(e)));
@ -263,13 +242,13 @@ where
}
}
impl<S, B> ResponseFuture<S>
impl<F, B> ResponseFuture<F>
where
B: Body,
S: svc::Service<Response = http::Response<B>>,
S::Error: HasH2Reason,
F: Future<Item = http::Response<B>>,
F::Error: HasH2Reason,
{
fn tap_err(&mut self, e: S::Error) -> S::Error {
fn tap_err(&mut self, e: F::Error) -> F::Error {
if let Some(request) = self.meta.take() {
let meta = event::Response {
request,

View File

@ -171,13 +171,13 @@ fn run(addr: SocketAddr, version: Run) -> (Sender, Running) {
.map_err(|e| println!("client error: {:?}", e)))
},
Run::Http2 => {
let connect = tower_h2::client::Connect::new(
let mut connect = tower_h2::client::Connect::new(
conn,
Default::default(),
LazyExecutor,
);
Box::new(connect.new_service()
Box::new(connect.call(())
.map_err(move |err| println!("connect error ({:?}): {:?}", addr, err))
.and_then(move |mut h2| {
rx.for_each(move |(req, cb)| {

View File

@ -99,11 +99,15 @@ impl Controller {
}
}
fn grpc_internal_code() -> grpc::Error {
grpc::Error::Grpc(grpc::Status::with_code(grpc::Code::Internal), HeaderMap::new())
}
impl Stream for DstReceiver {
type Item = pb::Update;
type Error = grpc::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
self.0.poll().map_err(|_| grpc::Error::Grpc(grpc::Status::INTERNAL, HeaderMap::new()))
self.0.poll().map_err(|_| grpc_internal_code())
}
}
@ -129,7 +133,7 @@ impl Stream for ProfileReceiver {
type Item = pb::DestinationProfile;
type Error = grpc::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
self.0.poll().map_err(|_| grpc::Error::Grpc(grpc::Status::INTERNAL, HeaderMap::new()))
self.0.poll().map_err(|_| grpc_internal_code())
}
}
@ -154,7 +158,7 @@ impl pb::server::Destination for Controller {
}
}
future::err(grpc::Error::Grpc(grpc::Status::INTERNAL, HeaderMap::new()))
future::err(grpc_internal_code())
}
type GetProfileStream = ProfileReceiver;
@ -171,7 +175,7 @@ impl pb::server::Destination for Controller {
}
}
future::err(grpc::Error::Grpc(grpc::Status::INTERNAL, HeaderMap::new()))
future::err(grpc_internal_code())
}
}
@ -212,7 +216,7 @@ fn run(controller: Controller, delay: Option<Box<Future<Item=(), Error=()> + Sen
}
let serve = bind.incoming()
.fold(h2, |h2, sock| {
.fold(h2, |mut h2, sock| {
if let Err(e) = sock.set_nodelay(true) {
return Err(e);
}

View File

@ -44,7 +44,7 @@ use self::tokio::{
use self::tokio_connect::Connect;
use self::tower_h2::{Body, RecvBody};
use self::tower_grpc as grpc;
use self::tower_service::{NewService, Service};
use self::tower_service::{Service};
/// Environment variable for overriding the test patience.
pub const ENV_TEST_PATIENCE_MS: &'static str = "RUST_TEST_PATIENCE_MS";

View File

@ -152,9 +152,9 @@ impl Server {
let mut runtime = runtime::current_thread::Runtime::new()
.expect("initialize support server runtime");
let new_svc = NewSvc(Arc::new(self.routes));
let mut new_svc = NewSvc(Arc::new(self.routes));
let srv: Box<Fn(TcpStream) -> Box<Future<Item=(), Error=()>>> = match self.version {
let srv: Box<FnMut(TcpStream) -> Box<Future<Item=(), Error=()>>> = match self.version {
Run::Http1 => {
let mut h1 = hyper::server::conn::Http::new();
h1.http1_only(true);
@ -162,7 +162,7 @@ impl Server {
Box::new(move |sock| {
let h1_clone = h1.clone();
let srv_conn_count = Arc::clone(&srv_conn_count);
let conn = new_svc.new_service()
let conn = new_svc.call(())
.inspect(move |_| {
srv_conn_count.fetch_add(1, Ordering::Release);
})
@ -176,7 +176,7 @@ impl Server {
})
},
Run::Http2 => {
let h2 = tower_h2::Server::new(
let mut h2 = tower_h2::Server::new(
new_svc,
Default::default(),
LazyExecutor,
@ -203,7 +203,7 @@ impl Server {
}
let serve = bind.incoming()
.fold(srv, move |srv, sock| {
.fold(srv, move |mut srv, sock| {
if let Err(e) = sock.set_nodelay(true) {
return Err(e);
}
@ -322,8 +322,7 @@ impl Svc {
}
}
impl Service for Svc {
type Request = Request<RecvBody>;
impl Service<Request<RecvBody>> for Svc {
type Response = Response<RspBody>;
type Error = h2::Error;
type Future = Box<Future<Item=Self::Response, Error=Self::Error> + Send>;
@ -332,7 +331,7 @@ impl Service for Svc {
Ok(Async::Ready(()))
}
fn call(&mut self, req: Self::Request) -> Self::Future {
fn call(&mut self, req: Request<RecvBody>) -> Self::Future {
let req = req.map(|body| {
assert!(body.is_end_stream(), "h2 test server doesn't support request bodies yet");
Box::new(futures::stream::empty()) as ReqBody
@ -373,15 +372,16 @@ impl hyper::service::Service for Svc {
#[derive(Debug)]
struct NewSvc(Arc<HashMap<String, Route>>);
impl NewService for NewSvc {
type Request = Request<RecvBody>;
type Response = Response<RspBody>;
type Error = h2::Error;
type InitError = ::std::io::Error;
type Service = Svc;
type Future = future::FutureResult<Svc, Self::InitError>;
impl Service<()> for NewSvc {
type Response = Svc;
type Error = ::std::io::Error;
type Future = future::FutureResult<Svc, Self::Error>;
fn new_service(&self) -> Self::Future {
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(Async::Ready(()))
}
fn call(&mut self, _: ()) -> Self::Future {
future::ok(Svc(Arc::clone(&self.0)))
}
}