Skip to content

Commit 5b348b8

Browse files
committed
feat(lib): add optional tcp feature, split from runtime
The `HttpConnector` and `AddrListener` types which make use of `tokio::tcp` have been made their own optional feature. This allows using them without requiring the *full* tokio runtime.
1 parent 02b5844 commit 5b348b8

File tree

10 files changed

+57
-43
lines changed

10 files changed

+57
-43
lines changed

Cargo.toml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,26 @@ futures-util-preview = { version = "=0.3.0-alpha.19" }
2727
http = "0.1.15"
2828
http-body = "=0.2.0-alpha.1"
2929
httparse = "1.0"
30-
# h2 = "=0.2.0-alpha.2"
3130
h2 = "=0.2.0-alpha.3"
3231
iovec = "0.1"
3332
itoa = "0.4.1"
3433
log = "0.4"
3534
net2 = { version = "0.2.32", optional = true }
3635
pin-project = "0.4"
3736
time = "0.1"
38-
tokio = { version = "=0.2.0-alpha.6", optional = true, default-features = false, features = ["rt-full"] }
3937
tower-service = "=0.3.0-alpha.2"
4038
tower-make = { version = "=0.3.0-alpha.2a", features = ['io'] }
41-
tokio-executor = { version = "=0.2.0-alpha.6", features = ["blocking"] }
39+
tokio-executor = "=0.2.0-alpha.6"
4240
tokio-io = "=0.2.0-alpha.6"
4341
tokio-sync = "=0.2.0-alpha.6"
42+
want = "0.3"
43+
44+
# Optional
45+
46+
tokio = { version = "=0.2.0-alpha.6", optional = true, default-features = false, features = ["rt-full"] }
4447
tokio-net = { version = "=0.2.0-alpha.6", optional = true, features = ["tcp"] }
4548
tokio-timer = { version = "=0.3.0-alpha.6", optional = true }
46-
want = "0.3"
49+
4750

4851
[dev-dependencies]
4952
matches = "0.1"
@@ -64,8 +67,12 @@ default = [
6467
"runtime",
6568
]
6669
runtime = [
67-
"net2",
70+
"tcp",
6871
"tokio",
72+
]
73+
tcp = [
74+
"net2",
75+
"tokio-executor/blocking",
6976
"tokio-net",
7077
"tokio-timer",
7178
]

src/client/connect/dns.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,15 +249,18 @@ impl Iterator for IpAddrs {
249249
///
250250
/// Unlike the `GaiResolver` this will not spawn dedicated threads, but only works when running on the
251251
/// multi-threaded Tokio runtime.
252+
#[cfg(feature = "runtime")]
252253
#[derive(Clone, Debug)]
253254
pub struct TokioThreadpoolGaiResolver(());
254255

255256
/// The future returned by `TokioThreadpoolGaiResolver`.
257+
#[cfg(feature = "runtime")]
256258
#[derive(Debug)]
257259
pub struct TokioThreadpoolGaiFuture {
258260
name: Name,
259261
}
260262

263+
#[cfg(feature = "runtime")]
261264
impl TokioThreadpoolGaiResolver {
262265
/// Creates a new DNS resolver that will use tokio threadpool's blocking
263266
/// feature.
@@ -268,6 +271,7 @@ impl TokioThreadpoolGaiResolver {
268271
}
269272
}
270273

274+
#[cfg(feature = "runtime")]
271275
impl Resolve for TokioThreadpoolGaiResolver {
272276
type Addrs = GaiAddrs;
273277
type Future = TokioThreadpoolGaiFuture;
@@ -277,6 +281,7 @@ impl Resolve for TokioThreadpoolGaiResolver {
277281
}
278282
}
279283

284+
#[cfg(feature = "runtime")]
280285
impl Future for TokioThreadpoolGaiFuture {
281286
type Output = Result<GaiAddrs, io::Error>;
282287

src/client/connect/http.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use tokio_timer::Delay;
1414

1515
use crate::common::{Future, Pin, Poll, task};
1616
use super::{Connect, Connected, Destination};
17-
use super::dns::{self, GaiResolver, Resolve, TokioThreadpoolGaiResolver};
17+
use super::dns::{self, GaiResolver, Resolve};
18+
#[cfg(feature = "runtime")] use super::dns::TokioThreadpoolGaiResolver;
1819

1920
// TODO: unbox me?
2021
type ConnectFuture = Pin<Box<dyn Future<Output = io::Result<TcpStream>> + Send>>;
@@ -81,6 +82,7 @@ impl HttpConnector {
8182
}
8283
}
8384

85+
#[cfg(feature = "runtime")]
8486
impl HttpConnector<TokioThreadpoolGaiResolver> {
8587
/// Construct a new HttpConnector using the `TokioThreadpoolGaiResolver`.
8688
///

src/client/connect/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use tokio_io::{AsyncRead, AsyncWrite};
1515

1616
use crate::common::{Future, Unpin};
1717

18-
#[cfg(feature = "runtime")] pub mod dns;
19-
#[cfg(feature = "runtime")] mod http;
20-
#[cfg(feature = "runtime")] pub use self::http::{HttpConnector, HttpInfo};
18+
#[cfg(feature = "tcp")] pub mod dns;
19+
#[cfg(feature = "tcp")] mod http;
20+
#[cfg(feature = "tcp")] pub use self::http::{HttpConnector, HttpInfo};
2121

2222
/// Connect to a destination, returning an IO transport.
2323
///

src/client/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
//! ```
3030
//! use hyper::{Client, Uri};
3131
//!
32-
//! # #[cfg(feature = "runtime")]
32+
//! # #[cfg(feature = "tcp")]
3333
//! # async fn fetch_httpbin() -> hyper::Result<()> {
3434
//! let client = Client::new();
3535
//!
@@ -75,7 +75,7 @@ use crate::common::{lazy as hyper_lazy, Lazy, Future, Pin, Poll, task};
7575
use self::connect::{Alpn, Connect, Connected, Destination};
7676
use self::pool::{Key as PoolKey, Pool, Poolable, Pooled, Reservation};
7777

78-
#[cfg(feature = "runtime")] pub use self::connect::HttpConnector;
78+
#[cfg(feature = "tcp")] pub use self::connect::HttpConnector;
7979

8080
pub mod conn;
8181
pub mod connect;
@@ -110,7 +110,7 @@ pub struct ResponseFuture {
110110

111111
// ===== impl Client =====
112112

113-
#[cfg(feature = "runtime")]
113+
#[cfg(feature = "tcp")]
114114
impl Client<HttpConnector, Body> {
115115
/// Create a new Client with the default [config](Builder).
116116
///
@@ -125,7 +125,7 @@ impl Client<HttpConnector, Body> {
125125
}
126126
}
127127

128-
#[cfg(feature = "runtime")]
128+
#[cfg(feature = "tcp")]
129129
impl Default for Client<HttpConnector, Body> {
130130
fn default() -> Client<HttpConnector, Body> {
131131
Client::new()
@@ -1018,7 +1018,7 @@ impl Builder {
10181018
}
10191019

10201020
/// Builder a client with this configuration and the default `HttpConnector`.
1021-
#[cfg(feature = "runtime")]
1021+
#[cfg(feature = "tcp")]
10221022
pub fn build_http<B>(&self) -> Client<HttpConnector, B>
10231023
where
10241024
B: Payload + Send,

src/common/exec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl Exec {
5050
{
5151
match *self {
5252
Exec::Default => {
53-
#[cfg(feature = "runtime")]
53+
#[cfg(feature = "tcp")]
5454
{
5555
use std::error::Error as StdError;
5656

@@ -81,7 +81,7 @@ impl Exec {
8181
crate::Error::new_execute(TokioSpawnError)
8282
})
8383
}
84-
#[cfg(not(feature = "runtime"))]
84+
#[cfg(not(feature = "tcp"))]
8585
{
8686
// If no runtime, we need an executor!
8787
panic!("executor must be set")

src/error.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub(crate) enum Kind {
3535
/// Error occurred while connecting.
3636
Connect,
3737
/// Error creating a TcpListener.
38-
#[cfg(feature = "runtime")]
38+
#[cfg(feature = "tcp")]
3939
Listen,
4040
/// Error accepting on an Incoming stream.
4141
Accept,
@@ -200,7 +200,7 @@ impl Error {
200200
Error::new(Kind::Io).with(cause)
201201
}
202202

203-
#[cfg(feature = "runtime")]
203+
#[cfg(feature = "tcp")]
204204
pub(crate) fn new_listen<E: Into<Cause>>(cause: E) -> Error {
205205
Error::new(Kind::Listen).with(cause)
206206
}
@@ -326,7 +326,7 @@ impl StdError for Error {
326326
Kind::ChannelClosed => "channel closed",
327327
Kind::Connect => "error trying to connect",
328328
Kind::Canceled => "operation was canceled",
329-
#[cfg(feature = "runtime")]
329+
#[cfg(feature = "tcp")]
330330
Kind::Listen => "error creating server listener",
331331
Kind::Accept => "error accepting connection",
332332
Kind::Body => "error reading a body from connection",

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
//! - `runtime` (*enabled by default*): Enables convenient integration with
2626
//! `tokio`, providing connectors and acceptors for TCP, and a default
2727
//! executor.
28+
//! - `tcp` (*enabled by default*): Enables convenient implementations over
29+
//! TCP (using tokio).
2830
//! - `unstable-stream` (*unstable*): Provides `futures::Stream` capabilities.
2931
//!
3032
//! Due to the `Stream` trait not being stable, this feature is also

src/server/conn.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
use std::error::Error as StdError;
1212
use std::fmt;
1313
use std::mem;
14-
#[cfg(feature = "runtime")] use std::net::SocketAddr;
15-
#[cfg(feature = "runtime")] use std::time::Duration;
14+
#[cfg(feature = "tcp")] use std::net::SocketAddr;
15+
#[cfg(feature = "tcp")] use std::time::Duration;
1616

1717
use bytes::Bytes;
1818
use futures_core::Stream;
1919
use tokio_io::{AsyncRead, AsyncWrite};
2020
use pin_project::{pin_project, project};
21-
#[cfg(feature = "runtime")] use tokio_net::driver::Handle;
21+
#[cfg(feature = "tcp")] use tokio_net::driver::Handle;
2222

2323
use crate::body::{Body, Payload};
2424
use crate::common::exec::{Exec, H2Exec, NewSvcExec};
@@ -35,7 +35,7 @@ use self::spawn_all::NewSvcTask;
3535
pub(super) use self::spawn_all::Watcher;
3636
pub(super) use self::upgrades::UpgradeableConnection;
3737

38-
#[cfg(feature = "runtime")] pub use super::tcp::{AddrIncoming, AddrStream};
38+
#[cfg(feature = "tcp")] pub use super::tcp::{AddrIncoming, AddrStream};
3939

4040
/// A lower-level configuration of the HTTP protocol.
4141
///
@@ -341,9 +341,7 @@ impl<E> Http<E> {
341341
/// # use hyper::{Body, Request, Response};
342342
/// # use hyper::service::Service;
343343
/// # use hyper::server::conn::Http;
344-
/// # #[cfg(feature = "runtime")]
345344
/// # use tokio_io::{AsyncRead, AsyncWrite};
346-
/// # #[cfg(feature = "runtime")]
347345
/// # async fn run<I, S>(some_io: I, some_service: S)
348346
/// # where
349347
/// # I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
@@ -404,7 +402,7 @@ impl<E> Http<E> {
404402
}
405403
}
406404

407-
#[cfg(feature = "runtime")]
405+
#[cfg(feature = "tcp")]
408406
#[doc(hidden)]
409407
#[deprecated]
410408
#[allow(deprecated)]
@@ -426,7 +424,7 @@ impl<E> Http<E> {
426424
Ok(self.serve_incoming(incoming, make_service))
427425
}
428426

429-
#[cfg(feature = "runtime")]
427+
#[cfg(feature = "tcp")]
430428
#[doc(hidden)]
431429
#[deprecated]
432430
#[allow(deprecated)]
@@ -792,7 +790,7 @@ where
792790

793791
// ===== impl SpawnAll =====
794792

795-
#[cfg(feature = "runtime")]
793+
#[cfg(feature = "tcp")]
796794
impl<S, E> SpawnAll<AddrIncoming, S, E> {
797795
pub(super) fn local_addr(&self) -> SocketAddr {
798796
self.serve.incoming.local_addr()

src/server/mod.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
//! use hyper::service::{make_service_fn, service_fn};
2424
//!
2525
//! # #[cfg(feature = "runtime")]
26-
//! # #[tokio::main]
26+
//! #[tokio::main]
2727
//! async fn main() {
2828
//! // Construct our SocketAddr to listen on...
2929
//! let addr = ([127, 0, 0, 1], 3000).into();
@@ -51,13 +51,13 @@
5151
pub mod accept;
5252
pub mod conn;
5353
mod shutdown;
54-
#[cfg(feature = "runtime")] mod tcp;
54+
#[cfg(feature = "tcp")] mod tcp;
5555

5656
use std::error::Error as StdError;
5757
use std::fmt;
58-
#[cfg(feature = "runtime")] use std::net::{SocketAddr, TcpListener as StdTcpListener};
58+
#[cfg(feature = "tcp")] use std::net::{SocketAddr, TcpListener as StdTcpListener};
5959

60-
#[cfg(feature = "runtime")] use std::time::Duration;
60+
#[cfg(feature = "tcp")] use std::time::Duration;
6161

6262
use tokio_io::{AsyncRead, AsyncWrite};
6363
use pin_project::pin_project;
@@ -71,7 +71,7 @@ use self::accept::Accept;
7171
// error that `hyper::server::Http` is private...
7272
use self::conn::{Http as Http_, NoopWatcher, SpawnAll};
7373
use self::shutdown::{Graceful, GracefulWatcher};
74-
#[cfg(feature = "runtime")] use self::tcp::AddrIncoming;
74+
#[cfg(feature = "tcp")] use self::tcp::AddrIncoming;
7575

7676
/// A listening HTTP server that accepts connections in both HTTP1 and HTTP2 by default.
7777
///
@@ -104,7 +104,7 @@ impl<I> Server<I, ()> {
104104
}
105105
}
106106

107-
#[cfg(feature = "runtime")]
107+
#[cfg(feature = "tcp")]
108108
impl Server<AddrIncoming, ()> {
109109
/// Binds to the provided address, and returns a [`Builder`](Builder).
110110
///
@@ -134,7 +134,7 @@ impl Server<AddrIncoming, ()> {
134134
}
135135
}
136136

137-
#[cfg(feature = "runtime")]
137+
#[cfg(feature = "tcp")]
138138
impl<S> Server<AddrIncoming, S> {
139139
/// Returns the local address that this server is bound to.
140140
pub fn local_addr(&self) -> SocketAddr {
@@ -162,7 +162,7 @@ where
162162
///
163163
/// ```
164164
/// # fn main() {}
165-
/// # #[cfg(feature = "runtime")]
165+
/// # #[cfg(feature = "tcp")]
166166
/// # async fn run() {
167167
/// # use hyper::{Body, Response, Server, Error};
168168
/// # use hyper::service::{make_service_fn, service_fn};
@@ -356,11 +356,8 @@ impl<I, E> Builder<I, E> {
356356
/// # Example
357357
///
358358
/// ```
359-
/// # #[cfg(not(feature = "runtime"))]
360-
/// # fn main() {}
361-
/// # #[cfg(feature = "runtime")]
362-
/// # #[tokio::main]
363-
/// # async fn main() {
359+
/// # #[cfg(feature = "tcp")]
360+
/// # async fn run() {
364361
/// use hyper::{Body, Error, Response, Server};
365362
/// use hyper::service::{make_service_fn, service_fn};
366363
///
@@ -378,7 +375,10 @@ impl<I, E> Builder<I, E> {
378375
/// let server = Server::bind(&addr)
379376
/// .serve(make_svc);
380377
///
381-
/// // Finally, spawn `server` onto an Executor...
378+
/// // Run forever-ish...
379+
/// if let Err(err) = server.await {
380+
/// eprintln!("server error: {}", err);
381+
/// }
382382
/// # }
383383
/// ```
384384
pub fn serve<S, B>(self, new_service: S) -> Server<I, S, E>
@@ -402,7 +402,7 @@ impl<I, E> Builder<I, E> {
402402
}
403403
}
404404

405-
#[cfg(feature = "runtime")]
405+
#[cfg(feature = "tcp")]
406406
impl<E> Builder<AddrIncoming, E> {
407407
/// Set whether TCP keepalive messages are enabled on accepted connections.
408408
///

0 commit comments

Comments
 (0)