Skip to content

Commit 99ed036

Browse files
committed
feat(client,service): completely remove tower-service crate, reimplement service::oneshot::Oneshot
1 parent ad706df commit 99ed036

File tree

9 files changed

+50
-134
lines changed

9 files changed

+50
-134
lines changed

Cargo.toml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ tokio = { version = "1", features = [
6565
] }
6666
tokio-test = "0.4"
6767
tokio-util = { version = "0.7", features = ["codec"] }
68-
tower = { version = "0.4", features = ["make", "util"] }
6968
url = "2.2"
7069

7170
[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dev-dependencies]
@@ -187,16 +186,6 @@ name = "state"
187186
path = "examples/state.rs"
188187
required-features = ["full"]
189188

190-
[[example]]
191-
name = "tower_client"
192-
path = "examples/tower_client.rs"
193-
required-features = ["full"]
194-
195-
[[example]]
196-
name = "tower_server"
197-
path = "examples/tower_server.rs"
198-
required-features = ["full"]
199-
200189
[[example]]
201190
name = "upgrades"
202191
path = "examples/upgrades.rs"

examples/service_struct_impl.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use hyper::{Body, Request, Response, Server};
33

44
use std::future::Future;
55
use std::pin::Pin;
6-
use std::task::{Context, Poll};
76

87
type Counter = i32;
98

src/client/client.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use super::HttpConnector;
2020
use crate::body::{Body, HttpBody};
2121
use crate::common::{exec::BoxSendFuture, sync_wrapper::SyncWrapper, lazy as hyper_lazy, task, Future, Lazy, Pin, Poll};
2222
use crate::rt::Executor;
23+
use crate::service::Service;
2324

2425
/// A Client to make outgoing HTTP requests.
2526
///
@@ -521,7 +522,7 @@ where
521522
}
522523
}
523524

524-
impl<C, B> tower_service::Service<Request<B>> for Client<C, B>
525+
impl<C, B> Service<Request<B>> for Client<C, B>
525526
where
526527
C: Connect + Clone + Send + Sync + 'static,
527528
B: HttpBody + Send + 'static,
@@ -532,16 +533,12 @@ where
532533
type Error = crate::Error;
533534
type Future = ResponseFuture;
534535

535-
fn poll_ready(&mut self, _: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
536-
Poll::Ready(Ok(()))
537-
}
538-
539536
fn call(&mut self, req: Request<B>) -> Self::Future {
540537
self.request(req)
541538
}
542539
}
543540

544-
impl<C, B> tower_service::Service<Request<B>> for &'_ Client<C, B>
541+
impl<C, B> Service<Request<B>> for &'_ Client<C, B>
545542
where
546543
C: Connect + Clone + Send + Sync + 'static,
547544
B: HttpBody + Send + 'static,
@@ -552,10 +549,6 @@ where
552549
type Error = crate::Error;
553550
type Future = ResponseFuture;
554551

555-
fn poll_ready(&mut self, _: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
556-
Poll::Ready(Ok(()))
557-
}
558-
559552
fn call(&mut self, req: Request<B>) -> Self::Future {
560553
self.request(req)
561554
}

src/client/connect/dns.rs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ use std::task::{self, Poll};
3030
use std::{fmt, io, vec};
3131

3232
use tokio::task::JoinHandle;
33-
use tower_service::Service;
3433
use tracing::debug;
34+
use crate::service::Service;
3535

3636
pub(super) use self::sealed::Resolve;
3737

@@ -113,10 +113,6 @@ impl Service<Name> for GaiResolver {
113113
type Error = io::Error;
114114
type Future = GaiFuture;
115115

116-
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {
117-
Poll::Ready(Ok(()))
118-
}
119-
120116
fn call(&mut self, name: Name) -> Self::Future {
121117
let blocking = tokio::task::spawn_blocking(move || {
122118
debug!("resolving host={:?}", name.host);
@@ -286,10 +282,6 @@ impl Service<Name> for TokioThreadpoolGaiResolver {
286282
type Error = io::Error;
287283
type Future = TokioThreadpoolGaiFuture;
288284
289-
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {
290-
Poll::Ready(Ok(()))
291-
}
292-
293285
fn call(&mut self, name: Name) -> Self::Future {
294286
TokioThreadpoolGaiFuture { name }
295287
}
@@ -319,16 +311,15 @@ impl Future for TokioThreadpoolGaiFuture {
319311

320312
mod sealed {
321313
use super::{SocketAddr, Name};
322-
use crate::common::{task, Future, Poll};
323-
use tower_service::Service;
314+
use crate::common::Future;
315+
use crate::service::Service;
324316

325317
// "Trait alias" for `Service<Name, Response = Addrs>`
326318
pub trait Resolve {
327319
type Addrs: Iterator<Item = SocketAddr>;
328320
type Error: Into<Box<dyn std::error::Error + Send + Sync>>;
329321
type Future: Future<Output = Result<Self::Addrs, Self::Error>>;
330322

331-
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
332323
fn resolve(&mut self, name: Name) -> Self::Future;
333324
}
334325

@@ -342,10 +333,6 @@ mod sealed {
342333
type Error = S::Error;
343334
type Future = S::Future;
344335

345-
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
346-
Service::poll_ready(self, cx)
347-
}
348-
349336
fn resolve(&mut self, name: Name) -> Self::Future {
350337
Service::call(self, name)
351338
}
@@ -356,7 +343,6 @@ pub(super) async fn resolve<R>(resolver: &mut R, name: Name) -> Result<R::Addrs,
356343
where
357344
R: Resolve,
358345
{
359-
futures_util::future::poll_fn(|cx| resolver.poll_ready(cx)).await?;
360346
resolver.resolve(name).await
361347
}
362348

src/client/connect/http.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use tracing::{debug, trace, warn};
1818

1919
use super::dns::{self, resolve, GaiResolver, Resolve};
2020
use super::{Connected, Connection};
21+
use crate::service::Service;
2122
//#[cfg(feature = "runtime")] use super::dns::TokioThreadpoolGaiResolver;
2223

2324
/// A connector for the `http` scheme.
@@ -251,7 +252,7 @@ impl<R: fmt::Debug> fmt::Debug for HttpConnector<R> {
251252
}
252253
}
253254

254-
impl<R> tower_service::Service<Uri> for HttpConnector<R>
255+
impl<R> Service<Uri> for HttpConnector<R>
255256
where
256257
R: Resolve + Clone + Send + Sync + 'static,
257258
R::Future: Send,
@@ -260,11 +261,6 @@ where
260261
type Error = ConnectError;
261262
type Future = HttpConnecting<R>;
262263

263-
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
264-
ready!(self.resolver.poll_ready(cx)).map_err(ConnectError::dns)?;
265-
Poll::Ready(Ok(()))
266-
}
267-
268264
fn call(&mut self, dst: Uri) -> Self::Future {
269265
let mut self_ = self.clone();
270266
HttpConnecting {

src/client/connect/mod.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@
4343
//! dyn Future<Output = Result<Self::Response, Self::Error>> + Send
4444
//! >>;
4545
//!
46-
//! fn poll_ready(&mut self, _: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
47-
//! // This connector is always ready, but others might not be.
48-
//! Poll::Ready(Ok(()))
49-
//! }
50-
//!
5146
//! fn call(&mut self, _: Uri) -> Self::Future {
5247
//! Box::pin(TcpStream::connect(SocketAddr::from(([127, 0, 0, 1], 1337))))
5348
//! }
@@ -276,6 +271,7 @@ pub(super) mod sealed {
276271

277272
use super::Connection;
278273
use crate::common::{Future, Unpin};
274+
use crate::service::Service;
279275

280276
/// Connect to a destination, returning an IO transport.
281277
///
@@ -306,28 +302,28 @@ pub(super) mod sealed {
306302

307303
impl<S, T> Connect for S
308304
where
309-
S: tower_service::Service<Uri, Response = T> + Send + 'static,
305+
S: Service<Uri, Response = T> + Send + 'static,
310306
S::Error: Into<Box<dyn StdError + Send + Sync>>,
311307
S::Future: Unpin + Send,
312308
T: AsyncRead + AsyncWrite + Connection + Unpin + Send + 'static,
313309
{
314310
type _Svc = S;
315311

316-
fn connect(self, _: Internal, dst: Uri) -> crate::service::Oneshot<S, Uri> {
312+
fn connect(self, _: Internal, dst: Uri) -> crate::service::Oneshot<S::Future> {
317313
crate::service::oneshot(self, dst)
318314
}
319315
}
320316

321317
impl<S, T> ConnectSvc for S
322318
where
323-
S: tower_service::Service<Uri, Response = T> + Send + 'static,
319+
S: Service<Uri, Response = T> + Send + 'static,
324320
S::Error: Into<Box<dyn StdError + Send + Sync>>,
325321
S::Future: Unpin + Send,
326322
T: AsyncRead + AsyncWrite + Connection + Unpin + Send + 'static,
327323
{
328324
type Connection = T;
329325
type Error = S::Error;
330-
type Future = crate::service::Oneshot<S, Uri>;
326+
type Future = crate::service::Oneshot<S::Future>;
331327

332328
fn connect(self, _: Internal, dst: Uri) -> Self::Future {
333329
crate::service::oneshot(self, dst)
@@ -336,7 +332,7 @@ pub(super) mod sealed {
336332

337333
impl<S, T> Sealed for S
338334
where
339-
S: tower_service::Service<Uri, Response = T> + Send,
335+
S: Service<Uri, Response = T> + Send,
340336
S::Error: Into<Box<dyn StdError + Send + Sync>>,
341337
S::Future: Unpin + Send,
342338
T: AsyncRead + AsyncWrite + Connection + Unpin + Send + 'static,

src/client/tests.rs

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
1-
use std::io;
2-
3-
use futures_util::future;
4-
use tokio::net::TcpStream;
5-
6-
use super::Client;
7-
8-
#[tokio::test]
9-
async fn client_connect_uri_argument() {
10-
let connector = tower::service_fn(|dst: http::Uri| {
11-
assert_eq!(dst.scheme(), Some(&http::uri::Scheme::HTTP));
12-
assert_eq!(dst.host(), Some("example.local"));
13-
assert_eq!(dst.port(), None);
14-
assert_eq!(dst.path(), "/", "path should be removed");
15-
16-
future::err::<TcpStream, _>(io::Error::new(io::ErrorKind::Other, "expect me"))
17-
});
18-
19-
let client = Client::builder().build::<_, crate::Body>(connector);
20-
let _ = client
21-
.get("http://example.local/and/a/path".parse().unwrap())
22-
.await
23-
.expect_err("response should fail");
24-
}
1+
// use std::io;
2+
//
3+
// use futures_util::future;
4+
// use tokio::net::TcpStream;
5+
// use crate::service::service_fn;
6+
//
7+
// use super::Client;
8+
//
9+
// #[tokio::test]
10+
// async fn client_connect_uri_argument() {
11+
// let connector = service_fn(|dst: http::Uri| {
12+
// assert_eq!(dst.scheme(), Some(&http::uri::Scheme::HTTP));
13+
// assert_eq!(dst.host(), Some("example.local"));
14+
// assert_eq!(dst.port(), None);
15+
// assert_eq!(dst.path(), "/", "path should be removed");
16+
//
17+
// future::err::<TcpStream, _>(io::Error::new(io::ErrorKind::Other, "expect me"))
18+
// });
19+
//
20+
// let client = Client::builder().build::<_, crate::Body>(connector);
21+
// let _ = client
22+
// .get("http://example.local/and/a/path".parse().unwrap())
23+
// .await
24+
// .expect_err("response should fail");
25+
// }
2526

2627
/*
2728
// FIXME: re-implement tests with `async/await`

src/service/oneshot.rs

Lines changed: 11 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,34 @@
1-
// TODO: Eventually to be replaced with tower_util::Oneshot.
2-
31
use pin_project_lite::pin_project;
4-
use tower_service::Service;
52

63
use crate::common::{task, Future, Pin, Poll};
4+
use crate::service::Service;
75

8-
pub(crate) fn oneshot<S, Req>(svc: S, req: Req) -> Oneshot<S, Req>
6+
pub(crate) fn oneshot<S, Req, F>(mut svc: S, req: Req) -> Oneshot<F>
97
where
10-
S: Service<Req>,
8+
S: Service<Req, Future = F>,
119
{
12-
Oneshot {
13-
state: State::NotReady { svc, req },
14-
}
10+
Oneshot { fut: svc.call(req) }
1511
}
1612

1713
pin_project! {
1814
// A `Future` consuming a `Service` and request, waiting until the `Service`
1915
// is ready, and then calling `Service::call` with the request, and
2016
// waiting for that `Future`.
2117
#[allow(missing_debug_implementations)]
22-
pub struct Oneshot<S: Service<Req>, Req> {
18+
pub struct Oneshot<F> {
2319
#[pin]
24-
state: State<S, Req>,
25-
}
26-
}
27-
28-
pin_project! {
29-
#[project = StateProj]
30-
#[project_replace = StateProjOwn]
31-
enum State<S: Service<Req>, Req> {
32-
NotReady {
33-
svc: S,
34-
req: Req,
35-
},
36-
Called {
37-
#[pin]
38-
fut: S::Future,
39-
},
40-
Tmp,
20+
fut: F,
4121
}
4222
}
4323

44-
impl<S, Req> Future for Oneshot<S, Req>
24+
impl<F, Response, Error> Future for Oneshot<F>
4525
where
46-
S: Service<Req>,
26+
F: Future<Output = Result<Response, Error>>,
4727
{
48-
type Output = Result<S::Response, S::Error>;
28+
type Output = Result<Response, Error>;
4929

5030
fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
51-
let mut me = self.project();
52-
53-
loop {
54-
match me.state.as_mut().project() {
55-
StateProj::NotReady { ref mut svc, .. } => {
56-
ready!(svc.poll_ready(cx))?;
57-
// fallthrough out of the match's borrow
58-
}
59-
StateProj::Called { fut } => {
60-
return fut.poll(cx);
61-
}
62-
StateProj::Tmp => unreachable!(),
63-
}
64-
65-
match me.state.as_mut().project_replace(State::Tmp) {
66-
StateProjOwn::NotReady { mut svc, req } => {
67-
me.state.set(State::Called { fut: svc.call(req) });
68-
}
69-
_ => unreachable!(),
70-
}
71-
}
31+
let me = self.project();
32+
me.fut.poll(cx)
7233
}
7334
}

tests/client.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,11 +2120,6 @@ mod dispatch_impl {
21202120
type Error = <HttpConnector as hyper::service::Service<Uri>>::Error;
21212121
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
21222122

2123-
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
2124-
// don't forget to check inner service is ready :)
2125-
hyper::service::Service::<Uri>::poll_ready(&mut self.http, cx)
2126-
}
2127-
21282123
fn call(&mut self, dst: Uri) -> Self::Future {
21292124
self.connects.fetch_add(1, Ordering::SeqCst);
21302125
let closes = self.closes.clone();

0 commit comments

Comments
 (0)