mirror of https://github.com/fafhrd91/actix-web
remove concurrency from fromrequest tuples
This commit is contained in:
parent
293c52c3ef
commit
6395f91bd9
|
@ -10,6 +10,7 @@ use std::{
|
||||||
use actix_http::http::{Method, Uri};
|
use actix_http::http::{Method, Uri};
|
||||||
use actix_utils::future::{ok, Ready};
|
use actix_utils::future::{ok, Ready};
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
|
use futures_util::future::{maybe_done, MaybeDone};
|
||||||
|
|
||||||
use crate::{dev::Payload, Error, HttpRequest};
|
use crate::{dev::Payload, Error, HttpRequest};
|
||||||
|
|
||||||
|
@ -297,7 +298,7 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||||
/// A helper struct to allow us to pin-project through
|
/// A helper struct to allow us to pin-project through
|
||||||
/// to individual fields
|
/// to individual fields
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
struct FutWrapper<$($T: FromRequest),+>($(#[pin] $T::Future),+);
|
struct FutWrapper<$($T: FromRequest),+>($(#[pin] MaybeDone<$T::Future>),+);
|
||||||
|
|
||||||
/// FromRequest implementation for tuple
|
/// FromRequest implementation for tuple
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -310,8 +311,7 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||||
|
|
||||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
||||||
$fut_type {
|
$fut_type {
|
||||||
items: <($(Option<$T>,)+)>::default(),
|
futs: FutWrapper($(maybe_done($T::from_request(req, payload)),)+),
|
||||||
futs: FutWrapper($($T::from_request(req, payload),)+),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,6 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct $fut_type<$($T: FromRequest),+> {
|
pub struct $fut_type<$($T: FromRequest),+> {
|
||||||
items: ($(Option<$T>,)+),
|
|
||||||
#[pin]
|
#[pin]
|
||||||
futs: FutWrapper<$($T,)+>,
|
futs: FutWrapper<$($T,)+>,
|
||||||
}
|
}
|
||||||
|
@ -329,28 +328,28 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||||
type Output = Result<($($T,)+), Error>;
|
type Output = Result<($($T,)+), Error>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let mut this = self.project();
|
let this = self.project();
|
||||||
|
let mut futs = this.futs.project();
|
||||||
|
|
||||||
let mut ready = true;
|
|
||||||
$(
|
$(
|
||||||
if this.items.$n.is_none() {
|
let mut fut = futs.$n.as_mut();
|
||||||
match this.futs.as_mut().project().$n.poll(cx) {
|
|
||||||
Poll::Ready(Ok(item)) => {
|
if fut.as_mut().output_mut().is_none() {
|
||||||
this.items.$n = Some(item);
|
ready!(fut.as_mut().poll(cx));
|
||||||
|
|
||||||
|
// this is a bit hacky, but we want to first check if there was an error
|
||||||
|
// before taking the output.
|
||||||
|
if let Some(Err(_)) = fut.as_mut().output_mut() {
|
||||||
|
if let Some(Err(e)) = fut.take_output() {
|
||||||
|
return Poll::Ready(Err(e.into()));
|
||||||
}
|
}
|
||||||
Poll::Pending => ready = false,
|
|
||||||
Poll::Ready(Err(e)) => return Poll::Ready(Err(e.into())),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
|
|
||||||
if ready {
|
|
||||||
Poll::Ready(Ok(
|
Poll::Ready(Ok(
|
||||||
($(this.items.$n.take().unwrap(),)+)
|
($(futs.$n.take_output().unwrap().unwrap_or_else(|_| unreachable!()),)+)
|
||||||
))
|
))
|
||||||
} else {
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue