perf(http1): propagate service user error generic further into dispatcher
In the case of `Never`, this allows the optimizer to eliminate more code inside the dispatcher, winning some more performance in benchmarks.
This commit is contained in:
		| @@ -5,6 +5,7 @@ use tokio_io::{AsyncRead, AsyncWrite}; | ||||
|  | ||||
| use body::{Body, Payload}; | ||||
| use body::internal::FullDataArg; | ||||
| use common::Never; | ||||
| use proto::{BodyLength, DecodedLength, Conn, Dispatched, MessageHead, RequestHead, RequestLine, ResponseHead}; | ||||
| use super::Http1Transaction; | ||||
| use service::Service; | ||||
| @@ -20,8 +21,9 @@ pub(crate) struct Dispatcher<D, Bs: Payload, I, T> { | ||||
| pub(crate) trait Dispatch { | ||||
|     type PollItem; | ||||
|     type PollBody; | ||||
|     type PollError; | ||||
|     type RecvItem; | ||||
|     fn poll_msg(&mut self) -> Poll<Option<(Self::PollItem, Self::PollBody)>, ::Error>; | ||||
|     fn poll_msg(&mut self) -> Poll<Option<(Self::PollItem, Self::PollBody)>, Self::PollError>; | ||||
|     fn recv_msg(&mut self, msg: ::Result<(Self::RecvItem, Body)>) -> ::Result<()>; | ||||
|     fn poll_ready(&mut self) -> Poll<(), ()>; | ||||
|     fn should_poll(&self) -> bool; | ||||
| @@ -42,6 +44,7 @@ type ClientRx<B> = ::client::dispatch::Receiver<Request<B>, Response<Body>>; | ||||
| impl<D, Bs, I, T> Dispatcher<D, Bs, I, T> | ||||
| where | ||||
|     D: Dispatch<PollItem=MessageHead<T::Outgoing>, PollBody=Bs, RecvItem=MessageHead<T::Incoming>>, | ||||
|     D::PollError: Into<Box<::std::error::Error + Send + Sync>>, | ||||
|     I: AsyncRead + AsyncWrite, | ||||
|     T: Http1Transaction, | ||||
|     Bs: Payload, | ||||
| @@ -231,7 +234,7 @@ where | ||||
|             if self.is_closing { | ||||
|                 return Ok(Async::Ready(())); | ||||
|             } else if self.body_rx.is_none() && self.conn.can_write_head() && self.dispatch.should_poll() { | ||||
|                 if let Some((head, mut body)) = try_ready!(self.dispatch.poll_msg()) { | ||||
|                 if let Some((head, mut body)) = try_ready!(self.dispatch.poll_msg().map_err(::Error::new_user_service)) { | ||||
|                     // Check if the body knows its full data immediately. | ||||
|                     // | ||||
|                     // If so, we can skip a bit of bookkeeping that streaming | ||||
| @@ -332,6 +335,7 @@ where | ||||
| impl<D, Bs, I, T> Future for Dispatcher<D, Bs, I, T> | ||||
| where | ||||
|     D: Dispatch<PollItem=MessageHead<T::Outgoing>, PollBody=Bs, RecvItem=MessageHead<T::Incoming>>, | ||||
|     D::PollError: Into<Box<::std::error::Error + Send + Sync>>, | ||||
|     I: AsyncRead + AsyncWrite, | ||||
|     T: Http1Transaction, | ||||
|     Bs: Payload, | ||||
| @@ -367,11 +371,12 @@ where | ||||
| { | ||||
|     type PollItem = MessageHead<StatusCode>; | ||||
|     type PollBody = Bs; | ||||
|     type PollError = S::Error; | ||||
|     type RecvItem = RequestHead; | ||||
|  | ||||
|     fn poll_msg(&mut self) -> Poll<Option<(Self::PollItem, Self::PollBody)>, ::Error> { | ||||
|     fn poll_msg(&mut self) -> Poll<Option<(Self::PollItem, Self::PollBody)>, Self::PollError> { | ||||
|         if let Some(mut fut) = self.in_flight.take() { | ||||
|             let resp = match fut.poll().map_err(::Error::new_user_service)? { | ||||
|             let resp = match fut.poll()? { | ||||
|                 Async::Ready(res) => res, | ||||
|                 Async::NotReady => { | ||||
|                     self.in_flight = Some(fut); | ||||
| @@ -432,9 +437,10 @@ where | ||||
| { | ||||
|     type PollItem = RequestHead; | ||||
|     type PollBody = B; | ||||
|     type PollError = Never; | ||||
|     type RecvItem = ResponseHead; | ||||
|  | ||||
|     fn poll_msg(&mut self) -> Poll<Option<(Self::PollItem, Self::PollBody)>, ::Error> { | ||||
|     fn poll_msg(&mut self) -> Poll<Option<(Self::PollItem, Self::PollBody)>, Never> { | ||||
|         match self.rx.poll() { | ||||
|             Ok(Async::Ready(Some((req, mut cb)))) => { | ||||
|                 // check that future hasn't been canceled already | ||||
|   | ||||
		Reference in New Issue
	
	Block a user