feat(lib): update to std::future::Future

BREAKING CHANGE: All usage of async traits (`Future`, `Stream`,
`AsyncRead`, `AsyncWrite`, etc) are updated to newer versions.
This commit is contained in:
Sean McArthur
2019-07-09 15:37:43 -07:00
parent da9b0319ef
commit 8f4b05ae78
37 changed files with 1526 additions and 1548 deletions

View File

@@ -4,12 +4,11 @@ use std::ops::{Deref, DerefMut};
use std::sync::{Arc, Mutex, Weak};
use std::time::{Duration, Instant};
use futures::{Future, Async, Poll};
use futures::sync::oneshot;
use futures_channel::oneshot;
#[cfg(feature = "runtime")]
use tokio_timer::Interval;
use crate::common::Exec;
use crate::common::{Exec, Future, Pin, Poll, Unpin, task};
use super::Ver;
// FIXME: allow() required due to `impl Trait` leaking types to this lint
@@ -24,7 +23,7 @@ pub(super) struct Pool<T> {
// This is a trait to allow the `client::pool::tests` to work for `i32`.
//
// See https://github.com/hyperium/hyper/issues/1429
pub(super) trait Poolable: Send + Sized + 'static {
pub(super) trait Poolable: Unpin + Send + Sized + 'static {
fn is_open(&self) -> bool;
/// Reserve this connection.
///
@@ -415,7 +414,7 @@ impl<T: Poolable> PoolInner<T> {
let start = Instant::now() + dur;
let interval = IdleInterval {
let interval = IdleTask {
interval: Interval::new(start, dur),
pool: WeakOpt::downgrade(pool_ref),
pool_drop_notifier: rx,
@@ -449,7 +448,7 @@ impl<T> PoolInner<T> {
#[cfg(feature = "runtime")]
impl<T: Poolable> PoolInner<T> {
/// This should *only* be called by the IdleInterval.
/// This should *only* be called by the IdleTask
fn clear_expired(&mut self) {
let dur = self.timeout.expect("interval assumes timeout");
@@ -569,25 +568,25 @@ pub(super) struct Checkout<T> {
}
impl<T: Poolable> Checkout<T> {
fn poll_waiter(&mut self) -> Poll<Option<Pooled<T>>, crate::Error> {
fn poll_waiter(&mut self, cx: &mut task::Context<'_>) -> Poll<Option<crate::Result<Pooled<T>>>> {
static CANCELED: &str = "pool checkout failed";
if let Some(mut rx) = self.waiter.take() {
match rx.poll() {
Ok(Async::Ready(value)) => {
match Pin::new(&mut rx).poll(cx) {
Poll::Ready(Ok(value)) => {
if value.is_open() {
Ok(Async::Ready(Some(self.pool.reuse(&self.key, value))))
Poll::Ready(Some(Ok(self.pool.reuse(&self.key, value))))
} else {
Err(crate::Error::new_canceled().with(CANCELED))
Poll::Ready(Some(Err(crate::Error::new_canceled().with(CANCELED))))
}
},
Ok(Async::NotReady) => {
Poll::Pending => {
self.waiter = Some(rx);
Ok(Async::NotReady)
Poll::Pending
},
Err(_canceled) => Err(crate::Error::new_canceled().with(CANCELED)),
Poll::Ready(Err(_canceled)) => Poll::Ready(Some(Err(crate::Error::new_canceled().with(CANCELED)))),
}
} else {
Ok(Async::Ready(None))
Poll::Ready(None)
}
}
@@ -622,9 +621,7 @@ impl<T: Poolable> Checkout<T> {
}
if entry.is_none() && self.waiter.is_none() {
let (tx, mut rx) = oneshot::channel();
let _ = rx.poll(); // park this task
let (tx, rx) = oneshot::channel();
trace!("checkout waiting for idle connection: {:?}", self.key);
inner
.waiters
@@ -643,20 +640,21 @@ impl<T: Poolable> Checkout<T> {
}
impl<T: Poolable> Future for Checkout<T> {
type Item = Pooled<T>;
type Error = crate::Error;
type Output = crate::Result<Pooled<T>>;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
if let Some(pooled) = try_ready!(self.poll_waiter()) {
return Ok(Async::Ready(pooled));
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
if let Some(pooled) = ready!(self.poll_waiter(cx)?) {
return Poll::Ready(Ok(pooled));
}
if let Some(pooled) = self.checkout() {
Ok(Async::Ready(pooled))
Poll::Ready(Ok(pooled))
} else if !self.pool.is_enabled() {
Err(crate::Error::new_canceled().with("pool is disabled"))
Poll::Ready(Err(crate::Error::new_canceled().with("pool is disabled")))
} else {
Ok(Async::NotReady)
// There's a new waiter, but there's no way it should be ready yet.
// We just need to register the waker.
self.poll_waiter(cx).map(|_| unreachable!())
}
}
}
@@ -717,37 +715,34 @@ impl Expiration {
}
#[cfg(feature = "runtime")]
struct IdleInterval<T> {
struct IdleTask<T> {
interval: Interval,
pool: WeakOpt<Mutex<PoolInner<T>>>,
// This allows the IdleInterval to be notified as soon as the entire
// This allows the IdleTask to be notified as soon as the entire
// Pool is fully dropped, and shutdown. This channel is never sent on,
// but Err(Canceled) will be received when the Pool is dropped.
pool_drop_notifier: oneshot::Receiver<crate::common::Never>,
}
#[cfg(feature = "runtime")]
impl<T: Poolable + 'static> Future for IdleInterval<T> {
type Item = ();
type Error = ();
impl<T: Poolable + 'static> Future for IdleTask<T> {
type Output = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
// Interval is a Stream
use futures::Stream;
use futures_core::Stream;
loop {
match self.pool_drop_notifier.poll() {
Ok(Async::Ready(n)) => match n {},
Ok(Async::NotReady) => (),
Err(_canceled) => {
match Pin::new(&mut self.pool_drop_notifier).poll(cx) {
Poll::Ready(Ok(n)) => match n {},
Poll::Pending => (),
Poll::Ready(Err(_canceled)) => {
trace!("pool closed, canceling idle interval");
return Ok(Async::Ready(()));
return Poll::Ready(());
}
}
try_ready!(self.interval.poll().map_err(|err| {
error!("idle interval timer error: {}", err);
}));
ready!(Pin::new(&mut self.interval).poll_next(cx));
if let Some(inner) = self.pool.upgrade() {
if let Ok(mut inner) = inner.lock() {
@@ -756,7 +751,7 @@ impl<T: Poolable + 'static> Future for IdleInterval<T> {
continue;
}
}
return Ok(Async::Ready(()));
return Poll::Ready(());
}
}
}