-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Limit futures
dependency to Stream
via feature flag
#1774
Conversation
In an effort to reach API stability, the `tokio` crate is shedding its _public_ dependencies on crates that are either a) do not provide a stable (1.0+) release with longevity guarantees or b) match the `tokio` release cadence. Of course, implmementing `std` traits fits the requirements. Instead of publically dependending on `futures` from `tokio`, the `tokio-util` crate provides the necessary bridge to go from Tokio types to `futures` traits (primarily `Stream`). Instead of implementing `Stream` for iteration, types that are logically streams provide `async fn next_*` functions to obtain the next value. Avoiding the `next()` function name will allow for forwards compatibility once the `Stream` trait is provided by `std`. Additionally, some misc cleanup is also done: - `tokio::io::io` -> `tokio::io::util`. - `delay` -> `delay_until`. - `Timeout::new` -> `timeout(...)`. - `signal::ctrl_c()` returns a future instead of a stream. - `{tcp,unix}::Incoming` is removed (due to lack of `Stream` trait). - `time::Throttle` is removed (due to lack of `Stream` trait).
The |
Any reason for choosing to define our own trait instead of depends on futures via feature flags? |
Even though I do understand the reasoning behind this move, it's nevertheless not easy to accept as it kind of feels like forced reinventing the wheel. After all, is |
After some discussion in discord: Tokio's next release isn't 1.0, so we can pull in |
Ok, based on feedback, I brought back a |
@ipetkov which fns? |
There's one (big) concern with an unstable feature flag: other dependencies can enable it, and a user doesn't realize they are using "unstable" APIs. This problem was noticed in Rayon, and they switched from an I've also noticed that warp master is depending on hyper's |
I agree that unstable feature flags aren’t a viable option. Since we aren’t hitting 1.0 and there is a path for Stream to land in std by 1.0 I say we stay optimistic |
@@ -122,7 +122,7 @@ impl Handle { | |||
/// The next operation in the mock's script will be to expect a `read` call | |||
/// and return `buf`. | |||
pub fn read(&mut self, buf: &[u8]) -> &mut Self { | |||
self.tx.try_send(Action::Read(buf.into())).unwrap(); | |||
self.tx.send(Action::Read(buf.into())).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unbounded mpsc send API changed to be more ergonomic.
@@ -524,7 +524,7 @@ async fn client_to_server() { | |||
drop(env_logger::try_init()); | |||
|
|||
// Create a server listening on a port, then figure out what that port is | |||
let srv = t!(TcpListener::bind("127.0.0.1:0").await); | |||
let mut srv = t!(TcpListener::bind("127.0.0.1:0").await); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
incoming
now takes &mut self
.
futures
dependency from tokio
futures
dependency to Stream
via feature flag
@@ -298,7 +298,7 @@ impl AsyncRead for Mock { | |||
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { | |||
if let Some(rem) = self.inner.remaining_wait() { | |||
let until = Instant::now() + rem; | |||
self.inner.sleep = Some(time::delay(until)); | |||
self.inner.sleep = Some(time::delay_until(until)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delay
was renamed delay_until
to further disambiguate from delay_for
.
@@ -40,7 +41,7 @@ blocking = ["rt-core"] | |||
dns = ["blocking"] | |||
fs = ["blocking"] | |||
io-driver = ["mio", "lazy_static", "sync"] # TODO: get rid of sync | |||
io-util = ["pin-project", "memchr"] | |||
io-util = ["pin-project", "pin-project-lite", "memchr"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying out pin-project-lite
, we probably should switch.
iovec = "0.1" | ||
|
||
# Everything else is optional... | ||
fnv = { version = "1.0.6", optional = true } | ||
futures-core = { version = "0.3.0", optional = true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only the Stream
trait is used.
|
||
/// A future that may have completed. | ||
#[derive(Debug)] | ||
pub(crate) enum MaybeDone<Fut: Future> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of dealing w/ refactoring internals to remove dependency on the few futures-util helpers, I copied them here as a temporary measure.
@@ -0,0 +1,15 @@ | |||
#![allow(unused_imports, dead_code)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really feel like figuring out which feature flags need which helpers. I hope that some of these can be removed.
#[cfg(feature = "io-util")] | ||
pub use self::io::{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move files from tokio::io::io
-> tokio::io::util
.
@@ -0,0 +1,44 @@ | |||
use std::future::Future; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like this file is unused.
In an effort to reach API stability, the
tokio
crate is shedding itspublic dependencies on crates that are either a) do not provide a
stable (1.0+) release with longevity guarantees or b) match the
tokio
release cadence. Of course, implementing
std
traits fits therequirements.
The on exception, for now, is the
Stream
trait found infutures_core
.It is expected that this trait will not change much and be moved into `std.
Since Tokio is not yet going reaching 1.0, I feel that it is acceptable to maintain
a dependency on this trait given how foundational it is.
Since the
Stream
implementation is optional, types that are logicallystreams provide
async fn next_*
functions to obtain the next value.Avoiding the
next()
name prevents fn conflicts withStreamExt::next()
.Additionally, some misc cleanup is also done:
tokio::io::io
->tokio::io::util
.delay
->delay_until
.Timeout::new
->timeout(...)
.signal::ctrl_c()
returns a future instead of a stream.{tcp,unix}::Incoming
is removed (due to lack ofStream
trait).time::Throttle
is removed (due to lack ofStream
trait).mpsc::UnboundedSender::send(&self)
(no more conflict withSink
fns).