Skip to content

Commit

Permalink
clean up exposed crate features (#50)
Browse files Browse the repository at this point in the history
- Put `TokioExecutor` and `TokioIo` into a single `rt::tokio` module.
- The `rt::tokio` module is behind a `tokio` crate feature.
- Changed `auto` crate feature to `server-auto`.
- Added `client-legacy` crate feature, with `client::legacy` behind it.
- Removed `tcp` and `runtime` features, code now depends on the `tokio`
  feature.
  • Loading branch information
seanmonstar authored Nov 16, 2023
1 parent 02dc44f commit c20cd20
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 85 deletions.
23 changes: 16 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ http = "1.0"
http-body = "1.0.0"
bytes = "1"
pin-project-lite = "0.2.4"
socket2 = "0.5"
socket2 = { version = "0.5", optional = true }
tracing = { version = "0.1", default-features = false, features = ["std"] }
tokio = { version = "1", features = ["net", "rt", "time"] }
tokio = { version = "1", optional = true, features = ["net", "rt", "time"] }
tower-service = "0.3"
tower = { version = "0.4", features = ["make", "util"] }

Expand All @@ -42,21 +42,30 @@ pnet_datalink = "0.34.0"
default = []

# Shorthand to enable everything
full = ["client", "server", "http1", "http2", "tcp", "auto", "runtime"]
full = [
"client",
"client-legacy",
"server",
"server-auto",
"http1",
"http2",
"tokio",
]

client = ["hyper/client"]
client-legacy = ["client"]

server = ["hyper/server"]
server-auto = ["hyper/server", "http1", "http2"]

http1 = ["hyper/http1"]
http2 = ["hyper/http2"]

tcp = []
auto = ["hyper/server", "http1", "http2"]
runtime = []
tokio = ["dep:tokio", "dep:socket2"]

# internal features used in CI
__internal_happy_eyeballs_tests = []

[[example]]
name = "client"
required-features = ["client", "http1", "tcp", "runtime"]
required-features = ["client-legacy", "http1", "tokio"]
18 changes: 9 additions & 9 deletions src/client/legacy/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use hyper::{body::Body, Method, Request, Response, Uri, Version};
use tracing::{debug, trace, warn};

use super::super::pool::{self, Ver};
#[cfg(feature = "tcp")]
#[cfg(feature = "tokio")]
use super::connect::HttpConnector;
use super::connect::{Alpn, Connect, Connected, Connection};
use crate::common::{lazy as hyper_lazy, Exec, Lazy, SyncWrapper};
Expand Down Expand Up @@ -103,7 +103,7 @@ impl Client<(), ()> {
/// # Example
///
/// ```
/// # #[cfg(feature = "runtime")]
/// # #[cfg(feature = "tokio")]
/// # fn run () {
/// use std::time::Duration;
/// use hyper::Client;
Expand Down Expand Up @@ -144,7 +144,7 @@ where
/// # Example
///
/// ```
/// # #[cfg(feature = "runtime")]
/// # #[cfg(feature = "tokio")]
/// # fn run () {
/// use hyper::{Client, Uri};
///
Expand Down Expand Up @@ -173,7 +173,7 @@ where
/// # Example
///
/// ```
/// # #[cfg(feature = "runtime")]
/// # #[cfg(feature = "tokio")]
/// # fn run () {
/// use hyper::{Method, Client, Request};
/// use http_body_util::Full;
Expand Down Expand Up @@ -934,7 +934,7 @@ fn is_schema_secure(uri: &Uri) -> bool {
/// # Example
///
/// ```
/// # #[cfg(feature = "runtime")]
/// # #[cfg(feature = "tokio")]
/// # fn run () {
/// use std::time::Duration;
/// use hyper::Client;
Expand Down Expand Up @@ -1286,7 +1286,7 @@ impl Builder {
/// # Cargo Feature
///
/// Requires the `runtime` cargo feature to be enabled.
#[cfg(feature = "runtime")]
#[cfg(feature = "tokio")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_keep_alive_interval(
Expand All @@ -1307,7 +1307,7 @@ impl Builder {
/// # Cargo Feature
///
/// Requires the `runtime` cargo feature to be enabled.
#[cfg(feature = "runtime")]
#[cfg(feature = "tokio")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_keep_alive_timeout(&mut self, timeout: Duration) -> &mut Self {
Expand All @@ -1327,7 +1327,7 @@ impl Builder {
/// # Cargo Feature
///
/// Requires the `runtime` cargo feature to be enabled.
#[cfg(feature = "runtime")]
#[cfg(feature = "tokio")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_keep_alive_while_idle(&mut self, enabled: bool) -> &mut Self {
Expand Down Expand Up @@ -1410,7 +1410,7 @@ impl Builder {
}

/// Builder a client with this configuration and the default `HttpConnector`.
#[cfg(feature = "tcp")]
#[cfg(feature = "tokio")]
pub fn build_http<B>(&self) -> Client<HttpConnector, B>
where
B: Body + Send,
Expand Down
3 changes: 3 additions & 0 deletions src/client/legacy/connect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,12 @@ use std::fmt;

use ::http::Extensions;

#[cfg(feature = "tokio")]
pub use self::http::{HttpConnector, HttpInfo};

#[cfg(feature = "tokio")]
pub mod dns;
#[cfg(feature = "tokio")]
mod http;

pub use self::sealed::Connect;
Expand Down
1 change: 1 addition & 0 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! HTTP client utilities

/// Legacy implementations of `connect` module and `Client`
#[cfg(feature = "client-legacy")]
pub mod legacy;
#[doc(hidden)]
pub mod pool;
28 changes: 7 additions & 21 deletions src/client/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ use std::pin::Pin;
use std::sync::{Arc, Mutex, Weak};
use std::task::{self, Poll};

#[cfg(not(feature = "runtime"))]
use std::time::{Duration, Instant};
#[cfg(feature = "runtime")]
use tokio::time::{Duration, Instant, Interval};

use futures_channel::oneshot;
use tracing::{debug, trace};
Expand Down Expand Up @@ -97,9 +94,7 @@ struct PoolInner<T, K: Eq + Hash> {
waiters: HashMap<K, VecDeque<oneshot::Sender<T>>>,
// A oneshot channel is used to allow the interval to be notified when
// the Pool completely drops. That way, the interval can cancel immediately.
#[cfg(feature = "runtime")]
idle_interval_ref: Option<oneshot::Sender<Infallible>>,
#[cfg(feature = "runtime")]
exec: Exec,
timeout: Option<Duration>,
}
Expand Down Expand Up @@ -130,11 +125,9 @@ impl<T, K: Key> Pool<T, K> {
Some(Arc::new(Mutex::new(PoolInner {
connecting: HashSet::new(),
idle: HashMap::new(),
#[cfg(feature = "runtime")]
idle_interval_ref: None,
max_idle_per_host: config.max_idle_per_host,
waiters: HashMap::new(),
#[cfg(feature = "runtime")]
exec,
timeout: config.idle_timeout,
})))
Expand All @@ -152,7 +145,6 @@ impl<T, K: Key> Pool<T, K> {
#[cfg(test)]
pub(super) fn no_timer(&self) {
// Prevent an actual interval from being created for this pool...
#[cfg(feature = "runtime")]
{
let mut inner = self.inner.as_ref().unwrap().lock().unwrap();
assert!(inner.idle_interval_ref.is_none(), "timer already spawned");
Expand Down Expand Up @@ -207,13 +199,11 @@ impl<T: Poolable, K: Key> Pool<T, K> {
}

/* Used in client/tests.rs...
#[cfg(feature = "runtime")]
#[cfg(test)]
pub(super) fn h1_key(&self, s: &str) -> Key {
Arc::new(s.to_string())
}
#[cfg(feature = "runtime")]
#[cfg(test)]
pub(super) fn idle_count(&self, key: &Key) -> usize {
self
Expand Down Expand Up @@ -403,10 +393,7 @@ impl<T: Poolable, K: Key> PoolInner<T, K> {
});
}

#[cfg(feature = "runtime")]
{
self.spawn_idle_interval(__pool_ref);
}
self.spawn_idle_interval(__pool_ref);
}
None => trace!("put; found waiter for {:?}", key),
}
Expand All @@ -423,8 +410,9 @@ impl<T: Poolable, K: Key> PoolInner<T, K> {
self.waiters.remove(key);
}

#[cfg(feature = "runtime")]
fn spawn_idle_interval(&mut self, pool_ref: &Arc<Mutex<PoolInner<T, K>>>) {
fn spawn_idle_interval(&mut self, _pool_ref: &Arc<Mutex<PoolInner<T, K>>>) {
// TODO
/*
let (dur, rx) = {
if self.idle_interval_ref.is_some() {
return;
Expand All @@ -446,6 +434,7 @@ impl<T: Poolable, K: Key> PoolInner<T, K> {
};
self.exec.execute(interval);
*/
}
}

Expand All @@ -466,7 +455,6 @@ impl<T, K: Eq + Hash> PoolInner<T, K> {
}
}

#[cfg(feature = "runtime")]
impl<T: Poolable, K: Key> PoolInner<T, K> {
/// This should *only* be called by the IdleTask
fn clear_expired(&mut self) {
Expand Down Expand Up @@ -766,7 +754,7 @@ impl Expiration {
}
}

#[cfg(feature = "runtime")]
/*
pin_project_lite::pin_project! {
struct IdleTask<T, K: Key> {
#[pin]
Expand All @@ -780,7 +768,6 @@ pin_project_lite::pin_project! {
}
}
#[cfg(feature = "runtime")]
impl<T: Poolable + 'static, K: Key> Future for IdleTask<T, K> {
type Output = ();
Expand Down Expand Up @@ -809,6 +796,7 @@ impl<T: Poolable + 'static, K: Key> Future for IdleTask<T, K> {
}
}
}
*/

impl<T> WeakOpt<T> {
fn none() -> Self {
Expand Down Expand Up @@ -932,7 +920,6 @@ mod tests {
assert!(is_not_ready);
}

#[cfg(feature = "runtime")]
#[tokio::test]
async fn test_pool_checkout_removes_expired() {
let pool = pool_no_timer();
Expand Down Expand Up @@ -971,7 +958,6 @@ mod tests {
);
}

#[cfg(feature = "runtime")]
#[tokio::test]
async fn test_pool_timer_removes_expired() {
tokio::time::pause();
Expand Down
9 changes: 4 additions & 5 deletions src/rt/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
//! Runtime utilities

/// Implementation of [`hyper::rt::Executor`] that utilises [`tokio::spawn`].
pub mod tokio_executor;
mod tokio_io;
#[cfg(feature = "tokio")]
pub mod tokio;

pub use tokio_executor::TokioExecutor;
pub use tokio_io::TokioIo;
#[cfg(feature = "tokio")]
pub use self::tokio::{TokioExecutor, TokioIo};
46 changes: 46 additions & 0 deletions src/rt/tokio_io.rs → src/rt/tokio.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
#![allow(dead_code)]
//! Tokio IO integration for hyper
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};

use hyper::rt::Executor;
use pin_project_lite::pin_project;

/// Future executor that utilises `tokio` threads.
#[non_exhaustive]
#[derive(Default, Debug, Clone)]
pub struct TokioExecutor {}

pin_project! {
/// A wrapping implementing hyper IO traits for a type that
/// implements Tokio's IO traits.
Expand All @@ -17,6 +24,27 @@ pin_project! {
}
}

// ===== impl TokioExecutor =====

impl<Fut> Executor<Fut> for TokioExecutor
where
Fut: Future + Send + 'static,
Fut::Output: Send + 'static,
{
fn execute(&self, fut: Fut) {
tokio::spawn(fut);
}
}

impl TokioExecutor {
/// Create new executor that relies on [`tokio::spawn`] to execute futures.
pub fn new() -> Self {
Self {}
}
}

// ==== impl TokioIo =====

impl<T> TokioIo<T> {
/// Wrap a type implementing Tokio's IO traits.
pub fn new(inner: T) -> Self {
Expand Down Expand Up @@ -161,3 +189,21 @@ where
hyper::rt::Write::poll_write_vectored(self.project().inner, cx, bufs)
}
}

#[cfg(test)]
mod tests {
use crate::rt::tokio_executor::TokioExecutor;
use hyper::rt::Executor;
use tokio::sync::oneshot;

#[cfg(not(miri))]
#[tokio::test]
async fn simple_execute() -> Result<(), Box<dyn std::error::Error>> {
let (tx, rx) = oneshot::channel();
let executor = TokioExecutor::new();
executor.execute(async move {
tx.send(()).unwrap();
});
rx.await.map_err(Into::into)
}
}
Loading

0 comments on commit c20cd20

Please sign in to comment.