Limit futures dependency to Stream via feature flag (#1774)

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, implementing `std` traits fits the
requirements.

The on exception, for now, is the `Stream` trait found in `futures_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 logically
streams provide `async fn next_*` functions to obtain the next value.
Avoiding the `next()` name prevents fn conflicts with `StreamExt::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 of `Stream` trait).
- `time::Throttle` is removed (due to lack of `Stream` trait).
-  Fix: `mpsc::UnboundedSender::send(&self)` (no more conflict with `Sink` fns).
This commit is contained in:
Carl Lerche
2019-11-15 22:11:13 -08:00
committed by GitHub
parent 930679587a
commit 8a7e57786a
130 changed files with 1763 additions and 1794 deletions
+16 -16
View File
@@ -58,7 +58,6 @@
//! use tokio::io::{BufReader, AsyncBufReadExt};
//! use tokio::process::Command;
//!
//! use futures_util::stream::StreamExt;
//! use std::process::Stdio;
//!
//! #[tokio::main]
@@ -89,8 +88,8 @@
//! println!("child status was: {}", status);
//! });
//!
//! while let Some(line) = reader.next().await {
//! println!("Line: {}", line?);
//! while let Some(line) = reader.next_line().await? {
//! println!("Line: {}", line);
//! }
//!
//! Ok(())
@@ -120,8 +119,6 @@ mod kill;
use crate::io::{AsyncRead, AsyncReadExt, AsyncWrite};
use crate::process::kill::Kill;
use futures_core::TryFuture;
use futures_util::future::try_join3;
use std::ffi::OsStr;
use std::future::Future;
use std::io;
@@ -681,11 +678,14 @@ impl<T: Kill> Drop for ChildDropGuard<T> {
}
}
impl<T: TryFuture + Kill + Unpin> Future for ChildDropGuard<T> {
type Output = Result<T::Ok, T::Error>;
impl<T, E, F> Future for ChildDropGuard<F>
where
F: Future<Output = Result<T, E>> + Kill + Unpin,
{
type Output = Result<T, E>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let ret = Pin::new(&mut self.inner).try_poll(cx);
let ret = Pin::new(&mut self.inner).poll(cx);
if let Poll::Ready(Ok(_)) = ret {
// Avoid the overhead of trying to kill a reaped process
@@ -766,6 +766,8 @@ impl Child {
/// new pipes between parent and child. Use `stdout(Stdio::piped())` or
/// `stderr(Stdio::piped())`, respectively, when creating a `Command`.
pub async fn wait_with_output(mut self) -> io::Result<Output> {
use crate::future::try_join3;
async fn read_to_end<A: AsyncRead + Unpin>(io: Option<A>) -> io::Result<Vec<u8>> {
let mut vec = Vec::new();
if let Some(mut io) = io {
@@ -940,16 +942,14 @@ mod sys {
#[cfg(all(test, not(loom)))]
mod test {
use super::kill::Kill;
use super::ChildDropGuard;
use futures::future::FutureExt;
use std::future::Future;
use std::io;
use std::pin::Pin;
use std::task::Context;
use std::task::Poll;
use futures_util::future::FutureExt;
use super::kill::Kill;
use super::ChildDropGuard;
use std::task::{Context, Poll};
struct Mock {
num_kills: usize,
@@ -1021,7 +1021,7 @@ mod test {
let mut mock_reaped = Mock::with_result(Poll::Ready(Ok(())));
let mut mock_err = Mock::with_result(Poll::Ready(Err(())));
let waker = futures_util::task::noop_waker();
let waker = futures::task::noop_waker();
let mut context = Context::from_waker(&waker);
{
let mut guard = ChildDropGuard::new(&mut mock_pending);