mirror of
https://github.com/fafhrd91/actix-net
synced 2025-01-18 13:01:49 +01:00
allow to send messages to framed transport via mpsc channel
This commit is contained in:
parent
ef1bdb2eb2
commit
e0d3581239
@ -1,5 +1,10 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* Allow to send messages to `FramedTransport` via mpsc channel.
|
||||||
|
|
||||||
|
|
||||||
## [0.3.4] - 2019-03-12
|
## [0.3.4] - 2019-03-12
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -7,6 +7,7 @@ use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed};
|
|||||||
use actix_service::{IntoNewService, IntoService, NewService, Service};
|
use actix_service::{IntoNewService, IntoService, NewService, Service};
|
||||||
use futures::future::{ok, FutureResult};
|
use futures::future::{ok, FutureResult};
|
||||||
use futures::task::AtomicTask;
|
use futures::task::AtomicTask;
|
||||||
|
use futures::unsync::mpsc;
|
||||||
use futures::{Async, Future, IntoFuture, Poll, Sink, Stream};
|
use futures::{Async, Future, IntoFuture, Poll, Sink, Stream};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
@ -178,6 +179,11 @@ impl<E, U: Encoder + Decoder> From<E> for FramedTransportError<E, U> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum FramedMessage<T> {
|
||||||
|
Message(T),
|
||||||
|
Close,
|
||||||
|
}
|
||||||
|
|
||||||
/// FramedTransport - is a future that reads frames from Framed object
|
/// FramedTransport - is a future that reads frames from Framed object
|
||||||
/// and pass then to the service.
|
/// and pass then to the service.
|
||||||
pub struct FramedTransport<S, T, U>
|
pub struct FramedTransport<S, T, U>
|
||||||
@ -193,6 +199,7 @@ where
|
|||||||
service: S,
|
service: S,
|
||||||
state: TransportState<S, U>,
|
state: TransportState<S, U>,
|
||||||
framed: Framed<T, U>,
|
framed: Framed<T, U>,
|
||||||
|
rx: Option<mpsc::UnboundedReceiver<FramedMessage<<U as Encoder>::Item>>>,
|
||||||
inner: Cell<FramedTransportInner<<U as Encoder>::Item, S::Error>>,
|
inner: Cell<FramedTransportInner<<U as Encoder>::Item, S::Error>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,6 +207,7 @@ enum TransportState<S: Service, U: Encoder + Decoder> {
|
|||||||
Processing,
|
Processing,
|
||||||
Error(FramedTransportError<S::Error, U>),
|
Error(FramedTransportError<S::Error, U>),
|
||||||
FramedError(FramedTransportError<S::Error, U>),
|
FramedError(FramedTransportError<S::Error, U>),
|
||||||
|
FlushAndStop,
|
||||||
Stopping,
|
Stopping,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,10 +265,12 @@ where
|
|||||||
/// write to framed object
|
/// write to framed object
|
||||||
fn poll_write(&mut self) -> bool {
|
fn poll_write(&mut self) -> bool {
|
||||||
let inner = self.inner.get_mut();
|
let inner = self.inner.get_mut();
|
||||||
|
let mut rx_done = self.rx.is_none();
|
||||||
|
let mut buf_empty = inner.buf.is_empty();
|
||||||
loop {
|
loop {
|
||||||
while !self.framed.is_write_buf_full() {
|
while !self.framed.is_write_buf_full() {
|
||||||
if let Some(msg) = inner.buf.pop_front() {
|
if !buf_empty {
|
||||||
match msg {
|
match inner.buf.pop_front().unwrap() {
|
||||||
Ok(msg) => {
|
Ok(msg) => {
|
||||||
if let Err(err) = self.framed.force_send(msg) {
|
if let Err(err) = self.framed.force_send(msg) {
|
||||||
self.state = TransportState::FramedError(
|
self.state = TransportState::FramedError(
|
||||||
@ -268,6 +278,7 @@ where
|
|||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
buf_empty = inner.buf.is_empty();
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
self.state =
|
self.state =
|
||||||
@ -275,7 +286,33 @@ where
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if !rx_done && self.rx.is_some() {
|
||||||
|
match self.rx.as_mut().unwrap().poll() {
|
||||||
|
Ok(Async::Ready(Some(FramedMessage::Message(msg)))) => {
|
||||||
|
if let Err(err) = self.framed.force_send(msg) {
|
||||||
|
self.state = TransportState::FramedError(
|
||||||
|
FramedTransportError::Encoder(err),
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Async::Ready(Some(FramedMessage::Close))) => {
|
||||||
|
self.state = TransportState::FlushAndStop;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Ok(Async::Ready(None)) => {
|
||||||
|
let _ = self.rx.take();
|
||||||
|
}
|
||||||
|
Ok(Async::NotReady) => rx_done = true,
|
||||||
|
Err(_e) => {
|
||||||
|
let _ = self.rx.take();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rx_done && buf_empty {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,6 +350,7 @@ where
|
|||||||
pub fn new<F: IntoService<S>>(framed: Framed<T, U>, service: F) -> Self {
|
pub fn new<F: IntoService<S>>(framed: Framed<T, U>, service: F) -> Self {
|
||||||
FramedTransport {
|
FramedTransport {
|
||||||
framed,
|
framed,
|
||||||
|
rx: None,
|
||||||
service: service.into_service(),
|
service: service.into_service(),
|
||||||
state: TransportState::Processing,
|
state: TransportState::Processing,
|
||||||
inner: Cell::new(FramedTransportInner {
|
inner: Cell::new(FramedTransportInner {
|
||||||
@ -322,6 +360,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get Sender
|
||||||
|
pub fn set_receiver(
|
||||||
|
mut self,
|
||||||
|
rx: mpsc::UnboundedReceiver<FramedMessage<<U as Encoder>::Item>>,
|
||||||
|
) -> Self {
|
||||||
|
self.rx = Some(rx);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Get reference to a service wrapped by `FramedTransport` instance.
|
/// Get reference to a service wrapped by `FramedTransport` instance.
|
||||||
pub fn get_ref(&self) -> &S {
|
pub fn get_ref(&self) -> &S {
|
||||||
&self.service
|
&self.service
|
||||||
@ -378,6 +425,20 @@ where
|
|||||||
Ok(Async::NotReady)
|
Ok(Async::NotReady)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TransportState::FlushAndStop => {
|
||||||
|
if !self.framed.is_write_buf_empty() {
|
||||||
|
match self.framed.poll_complete() {
|
||||||
|
Err(err) => {
|
||||||
|
debug!("Error sending data: {:?}", err);
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
|
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||||
|
Ok(Async::Ready(_)) => Ok(Async::Ready(())),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
TransportState::FramedError(err) => Err(err),
|
TransportState::FramedError(err) => Err(err),
|
||||||
TransportState::Stopping => Ok(Async::Ready(())),
|
TransportState::Stopping => Ok(Async::Ready(())),
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user