From d4b772d454e512d8591ce9f1822a552209577efb Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Mon, 24 Sep 2018 20:40:31 -0700 Subject: [PATCH] simplify FramedTransport --- src/framed.rs | 269 +++++++++++++------------------------------------- 1 file changed, 68 insertions(+), 201 deletions(-) diff --git a/src/framed.rs b/src/framed.rs index 11d4f2ab..10ea0c36 100644 --- a/src/framed.rs +++ b/src/framed.rs @@ -1,9 +1,9 @@ //! Framed dispatcher service and related utilities -use std::fmt; use std::marker::PhantomData; +use std::mem; use actix; -use futures::future::{ok, Either, FutureResult, Join}; +use futures::future::{ok, Either, FutureResult}; use futures::unsync::mpsc; use futures::{Async, AsyncSink, Future, Poll, Sink, Stream}; use tokio_codec::{Decoder, Encoder, Framed}; @@ -14,110 +14,97 @@ use service::{IntoNewService, IntoService, NewService, Service}; type Request = ::Item; type Response = ::Item; -pub struct FramedNewService { +pub struct FramedNewService { factory: S, - error_handler: E, _t: PhantomData<(T, U)>, } -impl FramedNewService> +impl FramedNewService where T: AsyncRead + AsyncWrite, U: Decoder + Encoder, S: NewService, Response = Option>> + Clone, <::Service as Service>::Future: 'static, - <::Service as Service>::Error: fmt::Debug + 'static, + <::Service as Service>::Error: 'static, ::Item: 'static, - ::Error: fmt::Debug + 'static, - ::Error: fmt::Debug + 'static, + ::Error: 'static, { pub fn new>(factory: F1) -> Self { Self { factory: factory.into_new_service(), - error_handler: DefaultErrorHandler(PhantomData), _t: PhantomData, } } } -impl Clone for FramedNewService +impl Clone for FramedNewService where S: Clone, - E: Clone, { fn clone(&self) -> Self { Self { factory: self.factory.clone(), - error_handler: self.error_handler.clone(), _t: PhantomData, } } } -impl NewService for FramedNewService +impl NewService for FramedNewService where T: AsyncRead + AsyncWrite, U: Decoder + Encoder, S: NewService, Response = Option>> + Clone, - E: NewService, InitError = S::InitError> + Clone, <::Service as Service>::Future: 'static, - <::Service as Service>::Error: fmt::Debug + 'static, + <::Service as Service>::Error: 'static, ::Item: 'static, - ::Error: fmt::Debug + 'static, - ::Error: fmt::Debug + 'static, + ::Error: 'static, { type Request = Framed; - type Response = FramedTransport; + type Response = FramedTransport; type Error = S::InitError; type InitError = S::InitError; - type Service = FramedService; + type Service = FramedService; type Future = FutureResult; fn new_service(&self) -> Self::Future { ok(FramedService { factory: self.factory.clone(), - error_service: self.error_handler.clone(), _t: PhantomData, }) } } -pub struct FramedService { +pub struct FramedService { factory: S, - error_service: E, _t: PhantomData<(T, U)>, } -impl Clone for FramedService +impl Clone for FramedService where S: Clone, - E: Clone, { fn clone(&self) -> Self { Self { factory: self.factory.clone(), - error_service: self.error_service.clone(), _t: PhantomData, } } } -impl Service for FramedService +impl Service for FramedService where T: AsyncRead + AsyncWrite, U: Decoder + Encoder, S: NewService, Response = Option>>, - E: NewService, InitError = S::InitError>, <::Service as Service>::Future: 'static, - <::Service as Service>::Error: fmt::Debug + 'static, + <::Service as Service>::Error: 'static, ::Item: 'static, - ::Error: fmt::Debug + 'static, - ::Error: fmt::Debug + 'static, + ::Error: 'static, { type Request = Framed; - type Response = FramedTransport; + type Response = FramedTransport; type Error = S::InitError; - type Future = FramedServiceResponseFuture; + type Future = FramedServiceResponseFuture; fn poll_ready(&mut self) -> Poll<(), Self::Error> { Ok(Async::Ready(())) @@ -125,129 +112,69 @@ where fn call(&mut self, req: Self::Request) -> Self::Future { FramedServiceResponseFuture { - fut: self - .factory - .new_service() - .join(self.error_service.new_service()), + fut: self.factory.new_service(), + framed: Some(req), } } } #[doc(hidden)] -pub struct FramedServiceResponseFuture +pub struct FramedServiceResponseFuture where T: AsyncRead + AsyncWrite, U: Decoder + Encoder, S: NewService, Response = Option>>, - E: NewService, InitError = S::InitError>, <::Service as Service>::Future: 'static, - <::Service as Service>::Error: fmt::Debug + 'static, + <::Service as Service>::Error: 'static, ::Item: 'static, - ::Error: fmt::Debug + 'static, - ::Error: fmt::Debug + 'static, + ::Error: 'static, { - fut: Join, + fut: S::Future, framed: Option>, } -impl Future for FramedServiceResponseFuture +impl Future for FramedServiceResponseFuture where T: AsyncRead + AsyncWrite, U: Decoder + Encoder, S: NewService, Response = Option>>, - E: NewService, InitError = S::InitError>, <::Service as Service>::Future: 'static, - <::Service as Service>::Error: fmt::Debug + 'static, + <::Service as Service>::Error: 'static, ::Item: 'static, - ::Error: fmt::Debug + 'static, - ::Error: fmt::Debug + 'static, + ::Error: 'static, { - type Item = FramedTransport; + type Item = FramedTransport; type Error = S::InitError; fn poll(&mut self) -> Poll { match self.fut.poll()? { Async::NotReady => Ok(Async::NotReady), - Async::Ready((service, error_service)) => { - Ok(Async::Ready(FramedTransport::with_error_service( - self.framed.take().unwrap(), - service, - error_service, - ))) - } + Async::Ready(service) => Ok(Async::Ready(FramedTransport::new( + self.framed.take().unwrap(), + service, + ))), } } } -pub enum TransportError { +/// Framed transport errors +pub enum FramedTransportError { Decoder(::Error), Encoder(::Error), Service(S::Error), } -/// Default error handling service -pub struct DefaultErrorHandler(PhantomData<(S, U, E)>); - -impl Service for DefaultErrorHandler -where - S: Service, - U: Encoder + Decoder, - S::Error: fmt::Debug, - ::Error: fmt::Debug, - ::Error: fmt::Debug, -{ - type Request = TransportError; - type Response = (); - type Error = (); - type Future = FutureResult; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - Ok(Async::Ready(())) - } - - fn call(&mut self, req: Self::Request) -> Self::Future { - match req { - TransportError::Service(err) => debug!("Service error: {:?}", err), - TransportError::Decoder(err) => trace!("Service decoder error: {:?}", err), - TransportError::Encoder(err) => trace!("Service encoder error: {:?}", err), - } - ok(()) - } -} - -impl NewService for DefaultErrorHandler -where - S: Service, - U: Encoder + Decoder, - S::Error: fmt::Debug, - ::Error: fmt::Debug, - ::Error: fmt::Debug, -{ - type Request = TransportError; - type Response = (); - type Error = (); - type InitError = E; - type Service = DefaultErrorHandler; - type Future = FutureResult; - - fn new_service(&self) -> Self::Future { - ok(DefaultErrorHandler(PhantomData)) - } -} - /// FramedTransport - is a future that reads frames from Framed object /// and pass then to the service. -pub struct FramedTransport +pub struct FramedTransport where S: Service, T: AsyncRead + AsyncWrite, U: Encoder + Decoder, - E: Service, { service: S, - error_service: E, - state: TransportState, + state: TransportState, framed: Framed, request: Option>, response: Option>, @@ -256,23 +183,21 @@ where flushed: bool, } -enum TransportState { +enum TransportState { Processing, - Error(E::Future), - EncoderError(E::Future), - SinkFlushing, + Error(FramedTransportError), + EncoderError(FramedTransportError), Stopping, } -impl FramedTransport> +impl FramedTransport where T: AsyncRead + AsyncWrite, U: Decoder + Encoder, S: Service, Response = Option>>, S::Future: 'static, - S::Error: fmt::Debug + 'static, - ::Error: fmt::Debug + 'static, - ::Error: fmt::Debug + 'static, + S::Error: 'static, + ::Error: 'static, { pub fn new>(framed: Framed, service: F) -> Self { let (write_tx, write_rx) = mpsc::channel(16); @@ -281,62 +206,24 @@ where write_rx, write_tx, service: service.into_service(), - error_service: DefaultErrorHandler(PhantomData), state: TransportState::Processing, request: None, response: None, flushed: true, } } - - /// Set error handler service - pub fn error_handler(self, handler: E) -> FramedTransport - where - E: Service>, - { - FramedTransport { - framed: self.framed, - request: self.request, - service: self.service, - write_rx: self.write_rx, - write_tx: self.write_tx, - response: self.response, - flushed: self.flushed, - state: TransportState::Processing, - error_service: handler, - } - } } -impl FramedTransport +impl FramedTransport where T: AsyncRead + AsyncWrite, U: Decoder + Encoder, S: Service, Response = Option>>, - E: Service>, S::Future: 'static, - S::Error: fmt::Debug + 'static, + S::Error: 'static, ::Item: 'static, - ::Error: fmt::Debug + 'static, - ::Error: fmt::Debug + 'static, + ::Error: 'static, { - pub fn with_error_service>( - framed: Framed, service: F, error_service: E, - ) -> Self { - let (write_tx, write_rx) = mpsc::channel(16); - FramedTransport { - framed, - write_rx, - write_tx, - error_service, - service: service.into_service(), - state: TransportState::Processing, - request: None, - response: None, - flushed: true, - } - } - fn poll_service(&mut self) -> bool { match self.service.poll_ready() { Ok(Async::Ready(_)) => { @@ -365,9 +252,8 @@ where return false; } Err(err) => { - self.state = TransportState::Error( - self.error_service.call(TransportError::Service(err)), - ); + self.state = + TransportState::Error(FramedTransportError::Service(err)); return true; } } @@ -375,9 +261,8 @@ where match self.framed.poll() { Ok(Async::Ready(Some(el))) => item = Some(el), Err(err) => { - self.state = TransportState::Error( - self.error_service.call(TransportError::Decoder(err)), - ); + self.state = + TransportState::Error(FramedTransportError::Decoder(err)); return true; } Ok(Async::NotReady) => return false, @@ -390,9 +275,7 @@ where } Ok(Async::NotReady) => return false, Err(err) => { - self.state = TransportState::Error( - self.error_service.call(TransportError::Service(err)), - ); + self.state = TransportState::Error(FramedTransportError::Service(err)); return true; } } @@ -408,10 +291,8 @@ where Ok(AsyncSink::Ready) => None, Ok(AsyncSink::NotReady(item)) => Some(item), Err(err) => { - trace!("Connection error: {:?}", err); - self.state = TransportState::EncoderError( - self.error_service.call(TransportError::Encoder(err)), - ); + self.state = + TransportState::EncoderError(FramedTransportError::Encoder(err)); return true; } } @@ -427,10 +308,8 @@ where } Ok(Async::NotReady) => break, Err(err) => { - trace!("Connection flush error: {:?}", err); - self.state = TransportState::EncoderError( - self.error_service.call(TransportError::Encoder(err)), - ); + self.state = + TransportState::EncoderError(FramedTransportError::Encoder(err)); return true; } } @@ -443,9 +322,8 @@ where Ok(Async::Ready(Some(msg))) => match msg { Ok(msg) => item = Some(msg), Err(err) => { - self.state = TransportState::Error( - self.error_service.call(TransportError::Service(err)), - ); + self.state = + TransportState::Error(FramedTransportError::Service(err)); return true; } }, @@ -466,23 +344,21 @@ where } } -impl Future for FramedTransport +impl Future for FramedTransport where T: AsyncRead + AsyncWrite, U: Decoder + Encoder, S: Service, Response = Option>>, S::Future: 'static, - S::Error: fmt::Debug + 'static, - E: Service>, + S::Error: 'static, ::Item: 'static, - ::Error: fmt::Debug + 'static, - ::Error: fmt::Debug + 'static, + ::Error: 'static, { type Item = (); - type Error = S::Error; + type Error = FramedTransportError; fn poll(&mut self) -> Poll { - let state = match self.state { + match mem::replace(&mut self.state, TransportState::Processing) { TransportState::Processing => { if self.poll_service() { return self.poll(); @@ -492,27 +368,18 @@ where } return Ok(Async::NotReady); } - TransportState::Error(ref mut fut) => match fut.poll() { - Err(_) | Ok(Async::Ready(_)) => TransportState::SinkFlushing, - _ => return Ok(Async::NotReady), - }, - TransportState::EncoderError(ref mut fut) => match fut.poll() { - Err(_) | Ok(Async::Ready(_)) => return Ok(Async::Ready(())), - _ => return Ok(Async::NotReady), - }, - TransportState::SinkFlushing => { + TransportState::Error(err) => { if self.poll_response() { - return self.poll(); + return Err(err); } if self.flushed { - return Ok(Async::Ready(())); + return Err(err); } + self.state = TransportState::Error(err); return Ok(Async::NotReady); } + TransportState::EncoderError(err) => return Err(err), TransportState::Stopping => return Ok(Async::Ready(())), - }; - - self.state = state; - self.poll() + } } }