refactor: improve the code for connection recycling

This avoids unnecessarily registering with the waker when we aren't going to poll until Ready.

Thanks to Kestrer on discord.
This commit is contained in:
Jeremiah Senkpiel 2021-03-06 19:56:25 -08:00
parent d129f07ca4
commit 70d180552d
4 changed files with 4 additions and 39 deletions

View File

@ -19,8 +19,6 @@ cfg_if::cfg_if! {
use super::{async_trait, Error, HttpClient, Request, Response};
pub(crate) mod utils;
mod tcp;
#[cfg(any(feature = "native-tls", feature = "rustls"))]
mod tls;

View File

@ -8,8 +8,6 @@ use deadpool::managed::{Manager, Object, RecycleResult};
use futures::io::{AsyncRead, AsyncWrite};
use futures::task::{Context, Poll};
use super::utils::PollRead;
#[derive(Clone, Debug)]
pub(crate) struct TcpConnection {
addr: SocketAddr,
@ -65,7 +63,8 @@ impl Manager<TcpStream, std::io::Error> for TcpConnection {
async fn recycle(&self, conn: &mut TcpStream) -> RecycleResult<std::io::Error> {
let mut buf = [0; 4];
match PollRead::new(conn, &mut buf).await {
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
match Pin::new(conn).poll_read(&mut cx, &mut buf) {
Poll::Ready(Err(error)) => Err(error),
Poll::Ready(Ok(bytes)) if bytes == 0 => Err(std::io::Error::new(
std::io::ErrorKind::UnexpectedEof,

View File

@ -8,8 +8,6 @@ use deadpool::managed::{Manager, Object, RecycleResult};
use futures::io::{AsyncRead, AsyncWrite};
use futures::task::{Context, Poll};
use super::utils::PollRead;
cfg_if::cfg_if! {
if #[cfg(feature = "rustls")] {
use async_tls::client::TlsStream;
@ -78,7 +76,8 @@ impl Manager<TlsStream<TcpStream>, Error> for TlsConnection {
async fn recycle(&self, conn: &mut TlsStream<TcpStream>) -> RecycleResult<Error> {
let mut buf = [0; 4];
match PollRead::new(conn, &mut buf).await {
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
match Pin::new(conn).poll_read(&mut cx, &mut buf) {
Poll::Ready(Err(error)) => Err(error),
Poll::Ready(Ok(bytes)) if bytes == 0 => Err(std::io::Error::new(
std::io::ErrorKind::UnexpectedEof,

View File

@ -1,31 +0,0 @@
use std::io;
use std::pin::Pin;
use futures::future::Future;
use futures::io::AsyncRead;
use futures::task::{Context, Poll};
/// Like the `futures::io::Read` future, but returning the underlying `futures::task::Poll`.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub(crate) struct PollRead<'a, R: ?Sized> {
reader: &'a mut R,
buf: &'a mut [u8],
}
impl<R: ?Sized + Unpin> Unpin for PollRead<'_, R> {}
impl<'a, R: AsyncRead + ?Sized + Unpin> PollRead<'a, R> {
pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self {
Self { reader, buf }
}
}
impl<R: AsyncRead + ?Sized + Unpin> Future for PollRead<'_, R> {
type Output = Poll<io::Result<usize>>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
Poll::Ready(Pin::new(&mut this.reader).poll_read(cx, this.buf))
}
}