diff --git a/tonic/src/transport/service/reconnect.rs b/tonic/src/transport/service/reconnect.rs index 5d1b5011d..151f36e73 100644 --- a/tonic/src/transport/service/reconnect.rs +++ b/tonic/src/transport/service/reconnect.rs @@ -13,11 +13,12 @@ use tracing::trace; pub(crate) struct Reconnect where M: Service, + M::Error: Into, { mk_service: M, state: State, target: Target, - error: Option, + error: Option, has_been_connected: bool, is_lazy: bool, } @@ -32,6 +33,7 @@ enum State { impl Reconnect where M: Service, + M::Error: Into, { pub(crate) fn new(mk_service: M, target: Target, is_lazy: bool) -> Self { Reconnect { @@ -52,14 +54,19 @@ where M::Future: Unpin, Error: From + From, Target: Clone, + >::Error: Into, { type Response = S::Response; type Error = Error; - type Future = ResponseFuture; + type Future = ResponseFuture; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { let mut state; + if self.error.is_some() { + return Poll::Ready(Ok(())); + } + loop { match self.state { State::Idle => { @@ -94,7 +101,9 @@ where if !(self.has_been_connected || self.is_lazy) { return Poll::Ready(Err(e.into())); } else { - self.error = Some(e); + let error = e.into(); + tracing::error!("reconnect::poll_ready: {:?}", error); + self.error = Some(error); break; } } @@ -130,8 +139,10 @@ where } fn call(&mut self, request: Request) -> Self::Future { + tracing::trace!("Reconnect::call"); if let Some(error) = self.error.take() { - return ResponseFuture::error(error); + tracing::error!("error: {:?}", error); + return ResponseFuture::error(error.into()); } let service = match self.state { @@ -150,6 +161,7 @@ where M::Future: fmt::Debug, M::Response: fmt::Debug, Target: fmt::Debug, + >::Error: Into, { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("Reconnect") @@ -163,37 +175,36 @@ where /// Future that resolves to the response or failure to connect. #[pin_project] #[derive(Debug)] -pub(crate) struct ResponseFuture { +pub(crate) struct ResponseFuture { #[pin] - inner: Inner, + inner: Inner, } #[pin_project(project = InnerProj)] #[derive(Debug)] -enum Inner { +enum Inner { Future(#[pin] F), - Error(Option), + Error(Option), } -impl ResponseFuture { +impl ResponseFuture { pub(crate) fn new(inner: F) -> Self { ResponseFuture { inner: Inner::Future(inner), } } - pub(crate) fn error(error: E) -> Self { + pub(crate) fn error(error: crate::Error) -> Self { ResponseFuture { inner: Inner::Error(Some(error)), } } } -impl Future for ResponseFuture +impl Future for ResponseFuture where F: Future>, E: Into, - ME: Into, { type Output = Result; @@ -203,7 +214,7 @@ where match me.inner.project() { InnerProj::Future(fut) => fut.poll(cx).map_err(Into::into), InnerProj::Error(e) => { - let e = e.take().expect("Polled after ready.").into(); + let e = e.take().expect("Polled after ready."); Poll::Ready(Err(e)) } }