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]] [[package]]
name = "codegen" name = "codegen"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/carllerche/codegen#9b2f81859e91931871456ad06437643585d35866" source = "git+https://github.com/carllerche/codegen#2d4dcc96f530ba163674d5efa985c3b133b3022e"
dependencies = [ 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]] [[package]]
@ -304,7 +304,7 @@ dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "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)", "string 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -381,7 +381,7 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.0.0" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -500,7 +500,7 @@ dependencies = [
"futures 0.1.23 (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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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-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 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-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-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-reconnect 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-service 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" version = "0.1.0"
dependencies = [ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "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", "linkerd2-stack 0.1.0",
"tower-service 0.1.0 (git+https://github.com/tower-rs/tower)", "tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
] ]
@ -1303,7 +1304,7 @@ dependencies = [
[[package]] [[package]]
name = "tower-add-origin" name = "tower-add-origin"
version = "0.1.0" 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 = [ dependencies = [
"futures 0.1.23 (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)", "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1313,10 +1314,10 @@ dependencies = [
[[package]] [[package]]
name = "tower-balance" name = "tower-balance"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85" source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1327,7 +1328,7 @@ dependencies = [
[[package]] [[package]]
name = "tower-buffer" name = "tower-buffer"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85" source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
@ -1336,7 +1337,7 @@ dependencies = [
[[package]] [[package]]
name = "tower-discover" name = "tower-discover"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85" source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
@ -1345,7 +1346,7 @@ dependencies = [
[[package]] [[package]]
name = "tower-grpc" name = "tower-grpc"
version = "0.1.0" 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 = [ dependencies = [
"bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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-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)", "tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
] ]
[[package]] [[package]]
name = "tower-grpc-build" name = "tower-grpc-build"
version = "0.1.0" 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 = [ dependencies = [
"codegen 0.1.0 (git+https://github.com/carllerche/codegen)", "codegen 0.1.0 (git+https://github.com/carllerche/codegen)",
"heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1370,7 +1372,7 @@ dependencies = [
[[package]] [[package]]
name = "tower-h2" name = "tower-h2"
version = "0.1.0" 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 = [ dependencies = [
"bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1385,7 +1387,7 @@ dependencies = [
[[package]] [[package]]
name = "tower-h2-balance" name = "tower-h2-balance"
version = "0.1.0" 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 = [ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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]] [[package]]
name = "tower-in-flight-limit" name = "tower-in-flight-limit"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85" source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "tower-service 0.1.0 (git+https://github.com/tower-rs/tower)",
@ -1407,7 +1420,7 @@ dependencies = [
[[package]] [[package]]
name = "tower-reconnect" name = "tower-reconnect"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85" source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1417,7 +1430,7 @@ dependencies = [
[[package]] [[package]]
name = "tower-service" name = "tower-service"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85" source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1425,7 +1438,7 @@ dependencies = [
[[package]] [[package]]
name = "tower-util" name = "tower-util"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/tower-rs/tower#b95c8d103056d9876b80b856b5f76754bf0f7b85" source = "git+https://github.com/tower-rs/tower#f21e3e4df07a3c474f6873b5e02a90e3e574ef46"
dependencies = [ dependencies = [
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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 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 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 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 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 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" "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-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 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-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-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-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>" "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-reconnect = { git = "https://github.com/tower-rs/tower" }
tower-service = { 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-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 = { git = "https://github.com/tower-rs/tower-h2" }
tower-h2-balance = { 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" } tower-grpc = { git = "https://github.com/tower-rs/tower-grpc" }

View File

@ -19,7 +19,7 @@ pub struct Router<Req, Rec, Stk>
where where
Rec: Recognize<Req>, Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>, Stk: stack::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>, Stk::Value: svc::Service<Req>,
{ {
inner: Arc<Inner<Req, Rec, Stk>>, inner: Arc<Inner<Req, Rec, Stk>>,
} }
@ -57,7 +57,7 @@ struct Inner<Req, Rec, Stk>
where where
Rec: Recognize<Req>, Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>, Stk: stack::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>, Stk::Value: svc::Service<Req>,
{ {
recognize: Rec, recognize: Rec,
make: Stk, make: Stk,
@ -95,7 +95,7 @@ impl<Req, Rec, Stk> Router<Req, Rec, Stk>
where where
Rec: Recognize<Req>, Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>, 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 { pub fn new(recognize: Rec, make: Stk, capacity: usize, max_idle_age: Duration) -> Self {
Router { 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 where
Rec: Recognize<Req>, Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>, 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<Req>>::Response;
type Response = <Stk::Value as svc::Service>::Response; type Error = Error<<Stk::Value as svc::Service<Req>>::Error, Stk::Error>;
type Error = Error<<Stk::Value as svc::Service>::Error, Stk::Error>; type Future = ResponseFuture<<Stk::Value as svc::Service<Req>>::Future, Stk::Error>;
type Future = ResponseFuture<<Stk::Value as svc::Service>::Future, Stk::Error>;
/// Always ready to serve. /// Always ready to serve.
/// ///
@ -133,7 +132,7 @@ where
/// Routes the request through an underlying service. /// Routes the request through an underlying service.
/// ///
/// The response fails when the request cannot be routed. /// 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) { let target = match self.inner.recognize.recognize(&request) {
Some(target) => target, Some(target) => target,
None => return ResponseFuture::not_recognized(), None => return ResponseFuture::not_recognized(),
@ -172,7 +171,7 @@ impl<Req, Rec, Stk> Clone for Router<Req, Rec, Stk>
where where
Rec: Recognize<Req>, Rec: Recognize<Req>,
Stk: stack::Stack<Rec::Target>, Stk: stack::Stack<Rec::Target>,
Stk::Value: svc::Service<Request = Req>, Stk::Value: svc::Service<Req>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Router { inner: self.inner.clone() } Router { inner: self.inner.clone() }
@ -311,8 +310,7 @@ mod test_util {
} }
} }
impl Service for MultiplyAndAssign { impl Service<Request> for MultiplyAndAssign {
type Request = Request;
type Response = usize; type Response = usize;
type Error = (); type Error = ();
type Future = future::FutureResult<usize, ()>; type Future = future::FutureResult<usize, ()>;
@ -321,7 +319,7 @@ mod test_util {
unimplemented!() unimplemented!()
} }
fn call(&mut self, req: Self::Request) -> Self::Future { fn call(&mut self, req: Request) -> Self::Future {
let n = match req { let n = match req {
Request::NotRecognized => unreachable!(), Request::NotRecognized => unreachable!(),
Request::Recognized(n) => n, 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 where
A: svc::Service, A: svc::Service<R>,
B: svc::Service<Request = A::Request, Response = A::Response>, B: svc::Service<R, Response = A::Response>,
{ {
type Request = A::Request;
type Response = A::Response; type Response = A::Response;
type Error = Either<A::Error, B::Error>; type Error = Either<A::Error, B::Error>;
type Future = future::Either< 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 { match self {
Either::A(ref mut a) => future::Either::A(a.call(req).map_err(Either::A)), 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)), 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; mod map_err;
pub mod map_target; pub mod map_target;
pub mod phantom_data; pub mod phantom_data;
pub mod stack_new_service; pub mod stack_make_service;
pub mod stack_per_request; pub mod stack_per_request;
pub mod watch; pub mod watch;
pub use self::either::Either; pub use self::either::Either;
pub use self::layer::Layer; pub use self::layer::Layer;
pub use self::stack_new_service::StackNewService; pub use self::stack_make_service::StackMakeService;
/// A composable builder. /// 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 === // === Service ===
impl<T, N> svc::Service for Service<T, N> impl<T, N, R> svc::Service<R> for Service<T, N>
where where
T: ShouldStackPerRequest + Clone, T: ShouldStackPerRequest + Clone,
N: super::Stack<T> + Clone, N: super::Stack<T> + Clone,
N::Value: svc::Service, N::Value: svc::Service<R>,
N::Error: fmt::Debug, N::Error: fmt::Debug,
{ {
type Request = <N::Value as svc::Service>::Request; type Response = <N::Value as svc::Service<R>>::Response;
type Response = <N::Value as svc::Service>::Response; type Error = <N::Value as svc::Service<R>>::Error;
type Error = <N::Value as svc::Service>::Error; type Future = <N::Value as svc::Service<R>>::Future;
type Future = <N::Value as svc::Service>::Future;
fn poll_ready(&mut self) -> Poll<(), Self::Error> { fn poll_ready(&mut self) -> Poll<(), Self::Error> {
if let Some(ref mut svc) = self.next { if let Some(ref mut svc) = self.next {
@ -114,7 +113,7 @@ where
Ok(ready) 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. // If a service has already been bound in `poll_ready`, consume it.
// Otherwise, bind a new service on-the-spot. // Otherwise, bind a new service on-the-spot.
self.next self.next

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,7 +35,8 @@ use futures::{
use indexmap::IndexMap; use indexmap::IndexMap;
use std::fmt; use std::fmt;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use tower_h2::{Body, BoxBody, Data, HttpService}; use tower_http::HttpService;
use tower_grpc::{Body, BoxBody};
use dns; use dns;
use transport::tls; use transport::tls;
@ -118,8 +119,8 @@ pub fn new<T>(
concurrency_limit: usize, concurrency_limit: usize,
) -> (Resolver, impl Future<Item = (), Error = ()>) ) -> (Resolver, impl Future<Item = (), Error = ()>)
where where
T: HttpService<RequestBody = BoxBody>, T: HttpService<BoxBody>,
T::ResponseBody: Body<Data = Data>, T::ResponseBody: Body,
T::Error: fmt::Debug, T::Error: fmt::Debug,
{ {
let (request_tx, rx) = mpsc::unbounded(); 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 { fn observe(&mut self, req: grpc::Request<ObserveRequest>) -> Self::ObserveFuture {
if self.next_id.load(Ordering::Acquire) == ::std::usize::MAX { if self.next_id.load(Ordering::Acquire) == ::std::usize::MAX {
return future::err(grpc::Error::Grpc( return future::err(grpc::Error::Grpc(
grpc::Status::INTERNAL, grpc::Status::with_code(grpc::Code::Internal),
HeaderMap::new(), HeaderMap::new(),
)); ));
} }
@ -58,7 +58,7 @@ impl server::Tap for Observe {
Some(m) => m, Some(m) => m,
None => { None => {
return future::err(grpc::Error::Grpc( return future::err(grpc::Error::Grpc(
grpc::Status::INVALID_ARGUMENT, grpc::Status::with_code(grpc::Code::InvalidArgument),
HeaderMap::new(), HeaderMap::new(),
)); ));
} }
@ -72,7 +72,7 @@ impl server::Tap for Observe {
} }
Err(_) => { Err(_) => {
return future::err(grpc::Error::Grpc( return future::err(grpc::Error::Grpc(
grpc::Status::INTERNAL, grpc::Status::with_code(grpc::Code::Internal),
HeaderMap::new(), HeaderMap::new(),
)); ));
} }

View File

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

View File

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

View File

@ -1,6 +1,6 @@
extern crate tower_buffer; extern crate tower_buffer;
use std::{error, fmt}; use std::{error, fmt, marker::PhantomData};
pub use self::tower_buffer::{Buffer, Error as ServiceError, SpawnError}; pub use self::tower_buffer::{Buffer, Error as ServiceError, SpawnError};
@ -8,13 +8,14 @@ use logging;
use svc; use svc;
/// Wraps `Service` stacks with a `Buffer`. /// Wraps `Service` stacks with a `Buffer`.
#[derive(Debug, Clone)] #[derive(Debug)]
pub struct Layer(); pub struct Layer<Req>(PhantomData<fn(Req)>);
/// Produces `Service`s wrapped with a `Buffer` /// Produces `Service`s wrapped with a `Buffer`
#[derive(Debug, Clone)] #[derive(Debug)]
pub struct Stack<M> { pub struct Stack<M, Req> {
inner: M, inner: M,
_marker: PhantomData<fn(Req)>,
} }
pub enum Error<M, S> { pub enum Error<M, S> {
@ -24,38 +25,56 @@ pub enum Error<M, S> {
// === impl Layer === // === impl Layer ===
pub fn layer() -> Layer { pub fn layer<Req>() -> Layer<Req> {
Layer() 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 where
T: fmt::Display + Clone + Send + Sync + 'static, T: fmt::Display + Clone + Send + Sync + 'static,
M: svc::Stack<T>, M: svc::Stack<T>,
M::Value: svc::Service + Send + 'static, M::Value: svc::Service<Req> + Send + 'static,
<M::Value as svc::Service>::Request: Send, <M::Value as svc::Service<Req>>::Future: Send,
<M::Value as svc::Service>::Future: Send, Req: Send + 'static,
{ {
type Value = <Stack<M> as svc::Stack<T>>::Value; type Value = <Stack<M, Req> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error; type Error = <Stack<M, Req> as svc::Stack<T>>::Error;
type Stack = Stack<M>; type Stack = Stack<M, Req>;
fn bind(&self, inner: M) -> Self::Stack { fn bind(&self, inner: M) -> Self::Stack {
Stack { inner } Stack {
inner,
_marker: PhantomData,
}
} }
} }
// === impl Stack === // === 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 where
T: fmt::Display + Clone + Send + Sync + 'static, T: fmt::Display + Clone + Send + Sync + 'static,
M: svc::Stack<T>, M: svc::Stack<T>,
M::Value: svc::Service + Send + 'static, M::Value: svc::Service<Req> + Send + 'static,
<M::Value as svc::Service>::Request: Send, <M::Value as svc::Service<Req>>::Future: Send,
<M::Value as svc::Service>::Future: Send, Req: Send + 'static,
{ {
type Value = Buffer<M::Value>; type Value = Buffer<M::Value, Req>;
type Error = Error<M::Error, M::Value>; type Error = Error<M::Error, M::Value>;
fn make(&self, target: &T) -> Result<Self::Value, Self::Error> { 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 impl<M> svc::Layer<Addr, Addr, M> for Layer
where where
M: svc::Stack<Addr> + Clone, M: svc::Stack<Addr> + Clone,
M::Value: svc::Service,
{ {
type Value = <Stack<M> as svc::Stack<Addr>>::Value; type Value = <Stack<M> as svc::Stack<Addr>>::Value;
type Error = <Stack<M> as svc::Stack<Addr>>::Error; type Error = <Stack<M> as svc::Stack<Addr>>::Error;
@ -94,7 +93,6 @@ where
impl<M> svc::Stack<Addr> for Stack<M> impl<M> svc::Stack<Addr> for Stack<M>
where where
M: svc::Stack<Addr> + Clone, M: svc::Stack<Addr> + Clone,
M::Value: svc::Service,
{ {
type Value = svc::Either<Service<M>, M::Value>; type Value = svc::Either<Service<M>, M::Value>;
type Error = M::Error; type Error = M::Error;
@ -120,7 +118,7 @@ where
impl<M> Service<M> impl<M> Service<M>
where where
M: svc::Stack<Addr>, M: svc::Stack<Addr>,
M::Value: svc::Service, //M::Value: svc::Service,
{ {
fn new(original: NameAddr, stack: M, resolver: dns::Resolver, timeout: Duration) -> Self { fn new(original: NameAddr, stack: M, resolver: dns::Resolver, timeout: Duration) -> Self {
trace!("refining name={}", original.name()); 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 where
M: svc::Stack<Addr>, 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<Req>>::Response;
type Response = <M::Value as svc::Service>::Response; type Error = Error<M::Error, <M::Value as svc::Service<Req>>::Error>;
type Error = Error<M::Error, <M::Value as svc::Service>::Error>;
type Future = future::MapErr< type Future = future::MapErr<
<M::Value as svc::Service>::Future, <M::Value as svc::Service<Req>>::Future,
fn(<M::Value as svc::Service>::Error) -> Self::Error, fn(<M::Value as svc::Service<Req>>::Error) -> Self::Error,
>; >;
fn poll_ready(&mut self) -> Poll<(), 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 self.service
.as_mut() .as_mut()
.expect("poll_ready must be called first") .expect("poll_ready must be called first")

View File

@ -2,39 +2,43 @@ extern crate tower_balance;
extern crate tower_discover; extern crate tower_discover;
extern crate tower_h2_balance; extern crate tower_h2_balance;
use http; use std::marker::PhantomData;
use std::time::Duration; use std::time::Duration;
use self::tower_discover::Discover; use self::tower_discover::Discover;
use tower_h2::Body;
pub use self::tower_balance::{choose::PowerOfTwoChoices, load::WithPeakEwma, Balance}; pub use self::tower_balance::{choose::PowerOfTwoChoices, load::WithPeakEwma, Balance};
pub use self::tower_h2_balance::{PendingUntilFirstData, PendingUntilFirstDataBody}; pub use self::tower_h2_balance::{PendingUntilFirstData, PendingUntilFirstDataBody};
use http;
use svc; use svc;
use tower_h2::Body;
/// Configures a stack to resolve `T` typed targets to balance requests over /// Configures a stack to resolve `T` typed targets to balance requests over
/// `M`-typed endpoint stacks. /// `M`-typed endpoint stacks.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct Layer { pub struct Layer<A, B> {
decay: Duration, decay: Duration,
_marker: PhantomData<fn(A) -> B>,
} }
/// Resolves `T` typed targets to balance requests over `M`-typed endpoint stacks. /// Resolves `T` typed targets to balance requests over `M`-typed endpoint stacks.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct Stack<M> { pub struct Stack<M, A, B> {
decay: Duration, decay: Duration,
inner: M, inner: M,
_marker: PhantomData<fn(A) -> B>,
} }
// === impl Layer === // === impl Layer ===
pub fn layer() -> Layer { pub fn layer<A, B>() -> Layer<A, B> {
Layer { Layer {
decay: Layer::DEFAULT_DECAY, decay: Layer::DEFAULT_DECAY,
_marker: PhantomData,
} }
} }
impl Layer { impl Layer<(), ()> {
const DEFAULT_DECAY: Duration = Duration::from_secs(10); const DEFAULT_DECAY: Duration = Duration::from_secs(10);
// pub fn with_decay(self, decay: Duration) -> Self { // 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 where
M: svc::Stack<T> + Clone, 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, A: Body,
B: Body, B: Body,
{ {
type Value = <Stack<M> as svc::Stack<T>>::Value; type Value = <Stack<M, A, B> as svc::Stack<T>>::Value;
type Error = <Stack<M> as svc::Stack<T>>::Error; type Error = <Stack<M, A, B> as svc::Stack<T>>::Error;
type Stack = Stack<M>; type Stack = Stack<M, A, B>;
fn bind(&self, inner: M) -> Self::Stack { fn bind(&self, inner: M) -> Self::Stack {
Stack { Stack {
decay: self.decay, decay: self.decay,
inner, inner,
_marker: PhantomData,
} }
} }
} }
// === impl Stack === // === 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 where
M: svc::Stack<T> + Clone, 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, A: Body,
B: 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 where
C: connect::Connect + Clone + Send + Sync + 'static, C: connect::Connect + Clone + Send + Sync + 'static,
C::Future: Send + 'static, C::Future: Send + 'static,
@ -315,20 +315,28 @@ where
B: tower_h2::Body + Send + 'static, B: tower_h2::Body + Send + 'static,
<B::Data as IntoBuf>::Buf: Send + 'static, <B::Data as IntoBuf>::Buf: Send + 'static,
{ {
type Request = <Self::Service as svc::Service>::Request; type Response = ClientService<C, E, B>;
type Response = <Self::Service as svc::Service>::Response; type Error = tower_h2::client::ConnectError<C::Error>;
type Error = <Self::Service as svc::Service>::Error;
type InitError = tower_h2::client::ConnectError<C::Error>;
type Service = ClientService<C, E, B>;
type Future = ClientNewServiceFuture<C, E, B>; 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 { let inner = match self.inner {
ClientInner::Http1(ref h1) => { ClientInner::Http1(ref h1) => {
ClientNewServiceFutureInner::Http1(Some(h1.clone())) ClientNewServiceFutureInner::Http1(Some(h1.clone()))
}, },
ClientInner::Http2(ref h2) => { ClientInner::Http2(ref mut h2) => {
ClientNewServiceFutureInner::Http2(h2.new_service()) ClientNewServiceFutureInner::Http2(h2.call(()))
}, },
}; };
ClientNewServiceFuture { ClientNewServiceFuture {
@ -370,7 +378,7 @@ where
// === impl ClientService === // === 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 where
C: connect::Connect + Send + Sync + 'static, C: connect::Connect + Send + Sync + 'static,
C::Connected: Send, C::Connected: Send,
@ -381,7 +389,6 @@ where
B: tower_h2::Body + Send + 'static, B: tower_h2::Body + Send + 'static,
<B::Data as IntoBuf>::Buf: Send + 'static, <B::Data as IntoBuf>::Buf: Send + 'static,
{ {
type Request = http::Request<B>;
type Response = http::Response<HttpBody>; type Response = http::Response<HttpBody>;
type Error = Error; type Error = Error;
type Future = ClientServiceFuture; 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={:?}", debug!("client request: method={} uri={} version={:?} headers={:?}",
req.method(), req.uri(), req.version(), req.headers()); req.method(), req.uri(), req.version(), req.headers());
match self.inner { 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> impl<S, E, B> hyper::service::Service for HyperServerSvc<S, E>
where where
S: svc::Service< S: svc::Service<
Request=http::Request<HttpBody>, http::Request<HttpBody>,
Response=http::Response<B>, Response=http::Response<B>,
>, >,
S::Error: Error + Send + Sync + 'static, S::Error: Error + Send + Sync + 'static,
@ -312,13 +312,12 @@ where
// ==== impl HttpBodySvc ==== // ==== impl HttpBodySvc ====
impl<S> svc::Service for HttpBodySvc<S> impl<S> svc::Service<http::Request<tower_h2::RecvBody>> for HttpBodySvc<S>
where where
S: svc::Service< S: svc::Service<
Request=http::Request<HttpBody>, http::Request<HttpBody>,
>, >,
{ {
type Request = http::Request<tower_h2::RecvBody>;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type Future = S::Future; type Future = S::Future;
@ -327,14 +326,14 @@ where
self.service.poll_ready() 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))) self.service.call(req.map(|b| HttpBody::Http2(b)))
} }
} }
impl<N> HttpBodyNewSvc<N> impl<N> HttpBodyNewSvc<N>
where where
N: svc::NewService<Request=http::Request<HttpBody>>, N: svc::MakeService<(), http::Request<HttpBody>>,
{ {
pub(in proxy) fn new(new_service: N) -> Self { pub(in proxy) fn new(new_service: N) -> Self {
HttpBodyNewSvc { HttpBodyNewSvc {
@ -343,20 +342,21 @@ where
} }
} }
impl<N> svc::NewService for HttpBodyNewSvc<N> impl<N> svc::Service<()> for HttpBodyNewSvc<N>
where where
N: svc::NewService<Request=http::Request<HttpBody>>, N: svc::MakeService<(), http::Request<HttpBody>>,
{ {
type Request = http::Request<tower_h2::RecvBody>; type Response = HttpBodySvc<N::Service>;
type Response = N::Response; type Error = N::MakeError;
type Error = N::Error;
type Service = HttpBodySvc<N::Service>;
type InitError = N::InitError;
type Future = HttpBodyNewSvcFuture<N::Future>; 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 { HttpBodyNewSvcFuture {
inner: self.new_service.new_service(), inner: self.new_service.make_service(target),
} }
} }
} }

View File

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

View File

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

View File

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

View File

@ -8,6 +8,7 @@ use std::sync::{Arc, Mutex};
use std::time::Instant; use std::time::Instant;
use tokio_timer::clock; use tokio_timer::clock;
use tower_h2; use tower_h2;
use tower_grpc;
use super::classify::{ClassifyEos, ClassifyResponse}; use super::classify::{ClassifyEos, ClassifyResponse};
use super::{ClassMetrics, Metrics, Registry, StatusMetrics}; use super::{ClassMetrics, Metrics, Registry, StatusMetrics};
@ -42,7 +43,6 @@ where
#[derive(Debug)] #[derive(Debug)]
pub struct Service<S, C> pub struct Service<S, C>
where where
S: svc::Service,
C: ClassifyResponse<Error = h2::Error> + Clone, C: ClassifyResponse<Error = h2::Error> + Clone,
C::Class: Hash + Eq, C::Class: Hash + Eq,
{ {
@ -51,16 +51,15 @@ where
_p: PhantomData<fn() -> C>, _p: PhantomData<fn() -> C>,
} }
pub struct ResponseFuture<S, C> pub struct ResponseFuture<F, C>
where where
S: svc::Service,
C: ClassifyResponse<Error = h2::Error>, C: ClassifyResponse<Error = h2::Error>,
C::Class: Hash + Eq, C::Class: Hash + Eq,
{ {
classify: Option<C>, classify: Option<C>,
metrics: Option<Arc<Mutex<Metrics<C::Class>>>>, metrics: Option<Arc<Mutex<Metrics<C::Class>>>>,
stream_open_at: Instant, stream_open_at: Instant,
inner: S::Future, inner: F,
} }
#[derive(Debug)] #[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 where
T: Clone + Debug, T: Clone + Debug,
K: Clone + Hash + Eq + From<T>, K: Clone + Hash + Eq + From<T>,
M: svc::Stack<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: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static,
C::Class: Hash + Eq, 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 where
T: Clone + Debug, T: Clone + Debug,
K: Clone + Hash + Eq + From<T>, K: Clone + Hash + Eq + From<T>,
M: svc::Stack<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: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static,
C::Class: Hash + Eq, C::Class: Hash + Eq,
{ {
@ -205,7 +192,7 @@ where
impl<S, C> Clone for Service<S, C> impl<S, C> Clone for Service<S, C>
where where
S: svc::Service + Clone, S: Clone,
C: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static, C: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static,
C::Class: Hash + Eq, 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 where
S: svc::Service< S: svc::Service<
Request = http::Request<RequestBody<A, C::Class>>, http::Request<RequestBody<A, C::Class>>,
Response = http::Response<B>, Response = http::Response<B>,
>, >,
A: tower_h2::Body, A: tower_h2::Body,
@ -229,16 +216,15 @@ where
C: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static, C: ClassifyResponse<Error = h2::Error> + Clone + Default + Send + Sync + 'static,
C::Class: Hash + Eq, C::Class: Hash + Eq,
{ {
type Request = http::Request<A>;
type Response = http::Response<ResponseBody<B, C::ClassifyEos>>; type Response = http::Response<ResponseBody<B, C::ClassifyEos>>;
type Error = S::Error; type Error = S::Error;
type Future = ResponseFuture<S, C>; type Future = ResponseFuture<S::Future, C>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> { fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.inner.poll_ready() 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(); let mut req_metrics = self.metrics.clone();
if req.body().is_end_stream() { 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 where
S: svc::Service<Response = http::Response<B>>, F: Future<Item = http::Response<B>>,
B: tower_h2::Body, B: tower_h2::Body,
C: ClassifyResponse<Error = h2::Error> + Send + Sync + 'static, C: ClassifyResponse<Error = h2::Error> + Send + Sync + 'static,
C::Class: Hash + Eq, C::Class: Hash + Eq,
{ {
type Item = http::Response<ResponseBody<B, C::ClassifyEos>>; 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> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let rsp = try_ready!(self.inner.poll()); 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> impl<B, C> Default for ResponseBody<B, C>
where where
B: tower_h2::Body + Default, 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> impl<B, C> Drop for ResponseBody<B, C>
where where
B: tower_h2::Body, B: tower_h2::Body,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -65,7 +65,6 @@ where
R: Resolve<T> + Clone, R: Resolve<T> + Clone,
R::Endpoint: fmt::Debug, R::Endpoint: fmt::Debug,
M: svc::Stack<R::Endpoint> + Clone, M: svc::Stack<R::Endpoint> + Clone,
M::Value: svc::Service,
{ {
type Value = <Stack<R, M> as svc::Stack<T>>::Value; type Value = <Stack<R, M> as svc::Stack<T>>::Value;
type Error = <Stack<R, M> as svc::Stack<T>>::Error; type Error = <Stack<R, M> as svc::Stack<T>>::Error;
@ -86,7 +85,6 @@ where
R: Resolve<T>, R: Resolve<T>,
R::Endpoint: fmt::Debug, R::Endpoint: fmt::Debug,
M: svc::Stack<R::Endpoint> + Clone, M: svc::Stack<R::Endpoint> + Clone,
M::Value: svc::Service,
{ {
type Value = Discover<R::Resolution, M>; type Value = Discover<R::Resolution, M>;
type Error = M::Error; type Error = M::Error;
@ -102,21 +100,17 @@ where
// === impl Discover === // === impl Discover ===
impl<R, M> tower_discover::Discover for Discover<R, M> impl<R, M> tower_discover::Discover for Discover<R, M>
where where
R: Resolution, R: Resolution,
R::Endpoint: fmt::Debug, R::Endpoint: fmt::Debug,
M: svc::Stack<R::Endpoint>, M: svc::Stack<R::Endpoint>,
M::Value: svc::Service,
{ {
type Key = SocketAddr; 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 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 { loop {
let up = try_ready!(self.resolution.poll().map_err(Error::Resolve)); let up = try_ready!(self.resolution.poll().map_err(Error::Resolve));
trace!("watch: {:?}", up); trace!("watch: {:?}", up);

View File

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

View File

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

View File

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

View File

@ -171,13 +171,13 @@ fn run(addr: SocketAddr, version: Run) -> (Sender, Running) {
.map_err(|e| println!("client error: {:?}", e))) .map_err(|e| println!("client error: {:?}", e)))
}, },
Run::Http2 => { Run::Http2 => {
let connect = tower_h2::client::Connect::new( let mut connect = tower_h2::client::Connect::new(
conn, conn,
Default::default(), Default::default(),
LazyExecutor, LazyExecutor,
); );
Box::new(connect.new_service() Box::new(connect.call(())
.map_err(move |err| println!("connect error ({:?}): {:?}", addr, err)) .map_err(move |err| println!("connect error ({:?}): {:?}", addr, err))
.and_then(move |mut h2| { .and_then(move |mut h2| {
rx.for_each(move |(req, cb)| { 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 { impl Stream for DstReceiver {
type Item = pb::Update; type Item = pb::Update;
type Error = grpc::Error; type Error = grpc::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::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 Item = pb::DestinationProfile;
type Error = grpc::Error; type Error = grpc::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::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; 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() let serve = bind.incoming()
.fold(h2, |h2, sock| { .fold(h2, |mut h2, sock| {
if let Err(e) = sock.set_nodelay(true) { if let Err(e) = sock.set_nodelay(true) {
return Err(e); return Err(e);
} }

View File

@ -44,7 +44,7 @@ use self::tokio::{
use self::tokio_connect::Connect; use self::tokio_connect::Connect;
use self::tower_h2::{Body, RecvBody}; use self::tower_h2::{Body, RecvBody};
use self::tower_grpc as grpc; use self::tower_grpc as grpc;
use self::tower_service::{NewService, Service}; use self::tower_service::{Service};
/// Environment variable for overriding the test patience. /// Environment variable for overriding the test patience.
pub const ENV_TEST_PATIENCE_MS: &'static str = "RUST_TEST_PATIENCE_MS"; 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() let mut runtime = runtime::current_thread::Runtime::new()
.expect("initialize support server runtime"); .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 => { Run::Http1 => {
let mut h1 = hyper::server::conn::Http::new(); let mut h1 = hyper::server::conn::Http::new();
h1.http1_only(true); h1.http1_only(true);
@ -162,7 +162,7 @@ impl Server {
Box::new(move |sock| { Box::new(move |sock| {
let h1_clone = h1.clone(); let h1_clone = h1.clone();
let srv_conn_count = Arc::clone(&srv_conn_count); let srv_conn_count = Arc::clone(&srv_conn_count);
let conn = new_svc.new_service() let conn = new_svc.call(())
.inspect(move |_| { .inspect(move |_| {
srv_conn_count.fetch_add(1, Ordering::Release); srv_conn_count.fetch_add(1, Ordering::Release);
}) })
@ -176,7 +176,7 @@ impl Server {
}) })
}, },
Run::Http2 => { Run::Http2 => {
let h2 = tower_h2::Server::new( let mut h2 = tower_h2::Server::new(
new_svc, new_svc,
Default::default(), Default::default(),
LazyExecutor, LazyExecutor,
@ -203,7 +203,7 @@ impl Server {
} }
let serve = bind.incoming() let serve = bind.incoming()
.fold(srv, move |srv, sock| { .fold(srv, move |mut srv, sock| {
if let Err(e) = sock.set_nodelay(true) { if let Err(e) = sock.set_nodelay(true) {
return Err(e); return Err(e);
} }
@ -322,8 +322,7 @@ impl Svc {
} }
} }
impl Service for Svc { impl Service<Request<RecvBody>> for Svc {
type Request = Request<RecvBody>;
type Response = Response<RspBody>; type Response = Response<RspBody>;
type Error = h2::Error; type Error = h2::Error;
type Future = Box<Future<Item=Self::Response, Error=Self::Error> + Send>; type Future = Box<Future<Item=Self::Response, Error=Self::Error> + Send>;
@ -332,7 +331,7 @@ impl Service for Svc {
Ok(Async::Ready(())) 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| { let req = req.map(|body| {
assert!(body.is_end_stream(), "h2 test server doesn't support request bodies yet"); assert!(body.is_end_stream(), "h2 test server doesn't support request bodies yet");
Box::new(futures::stream::empty()) as ReqBody Box::new(futures::stream::empty()) as ReqBody
@ -373,15 +372,16 @@ impl hyper::service::Service for Svc {
#[derive(Debug)] #[derive(Debug)]
struct NewSvc(Arc<HashMap<String, Route>>); struct NewSvc(Arc<HashMap<String, Route>>);
impl NewService for NewSvc { impl Service<()> for NewSvc {
type Request = Request<RecvBody>; type Response = Svc;
type Response = Response<RspBody>; type Error = ::std::io::Error;
type Error = h2::Error; type Future = future::FutureResult<Svc, Self::Error>;
type InitError = ::std::io::Error;
type Service = Svc;
type Future = future::FutureResult<Svc, Self::InitError>;
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))) future::ok(Svc(Arc::clone(&self.0)))
} }
} }