Flush&Sync per message type; Rewrite select receivers;
This commit is contained in:
parent
18bd3c63f4
commit
c927dad70e
@ -1,15 +1,15 @@
|
|||||||
|
use messagebus::derive::Message;
|
||||||
use messagebus::error::GenericError;
|
use messagebus::error::GenericError;
|
||||||
use messagebus::{Bus, TypeTagged};
|
use messagebus::{Bus, TypeTagged};
|
||||||
use messagebus_remote::relays::QuicClientRelay;
|
use messagebus_remote::relays::QuicClientRelay;
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use messagebus::derive::Message;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Message)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Message)]
|
||||||
#[namespace("example")]
|
#[namespace("example")]
|
||||||
#[message(shared, clone)]
|
#[message(shared, clone)]
|
||||||
pub struct Req {
|
pub struct Req {
|
||||||
data: i32,
|
data: i32,
|
||||||
text: String
|
text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Message)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Message)]
|
||||||
@ -17,39 +17,44 @@ pub struct Req {
|
|||||||
#[message(shared, clone)]
|
#[message(shared, clone)]
|
||||||
pub struct Resp {
|
pub struct Resp {
|
||||||
data: i32,
|
data: i32,
|
||||||
text: String
|
text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let relay = QuicClientRelay::new(
|
let relay = QuicClientRelay::new(
|
||||||
"./examples/cert.der",
|
"./examples/cert.der",
|
||||||
"127.0.0.1:8083".parse().unwrap(),
|
"127.0.0.1:8083".parse().unwrap(),
|
||||||
"localhost".into(),
|
"localhost".into(),
|
||||||
(vec![
|
(
|
||||||
(Req::type_tag_(), Some((Resp::type_tag_(), GenericError::type_tag_())))
|
vec![(
|
||||||
],
|
Req::type_tag_(),
|
||||||
vec![])
|
Some((Resp::type_tag_(), GenericError::type_tag_())),
|
||||||
).unwrap();
|
)],
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let (b, poller) = Bus::build()
|
let (b, poller) = Bus::build().register_relay(relay).build();
|
||||||
.register_relay(relay)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
|
||||||
b.ready().await;
|
b.ready().await;
|
||||||
println!("ready");
|
println!("ready");
|
||||||
|
|
||||||
let resp: Resp = b.request(Req {
|
let resp: Resp = b
|
||||||
data: 12,
|
.request(
|
||||||
text: String::from("test")
|
Req {
|
||||||
}, Default::default())
|
data: 12,
|
||||||
.await
|
text: String::from("test"),
|
||||||
.unwrap();
|
},
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
println!("resp {:?}", resp);
|
println!("resp {:?}", resp);
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
b.close().await;
|
b.close().await;
|
||||||
poller.await;
|
poller.await;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ async fn main() {
|
|||||||
|
|
||||||
println!("resp {:?}", resp);
|
println!("resp {:?}", resp);
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
b.close().await;
|
b.close().await;
|
||||||
poller.await;
|
poller.await;
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,21 @@ mod client;
|
|||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use bytes::{Buf, BufMut};
|
||||||
pub use client::QuicClientEndpoint;
|
pub use client::QuicClientEndpoint;
|
||||||
|
use futures::{pin_mut, Future, Stream, StreamExt};
|
||||||
use messagebus::error::GenericError;
|
use messagebus::error::GenericError;
|
||||||
use messagebus::{Action, Bus, Event, EventBoxed, Message, ReciveUntypedReceiver, SendOptions, SendUntypedReceiver, TypeTag, TypeTagAccept};
|
use messagebus::{
|
||||||
|
Action, Bus, Event, EventBoxed, Message, ReciveUntypedReceiver, SendOptions,
|
||||||
|
SendUntypedReceiver, TypeTag, TypeTagAccept,
|
||||||
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use quinn::{Connecting, IncomingBiStreams};
|
use quinn::{Connecting, IncomingBiStreams};
|
||||||
pub use server::QuicServerEndpoint;
|
pub use server::QuicServerEndpoint;
|
||||||
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
|
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
|
||||||
use futures::{Future, Stream, StreamExt, pin_mut};
|
|
||||||
use bytes::{Buf, BufMut};
|
|
||||||
|
|
||||||
pub const ALPN_QUIC_HTTP: &[&[u8]] = &[b"hq-29"];
|
pub const ALPN_QUIC_HTTP: &[&[u8]] = &[b"hq-29"];
|
||||||
|
|
||||||
@ -47,7 +50,12 @@ pub struct QuicRelay<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl QuicRelay<QuicClientEndpoint> {
|
impl QuicRelay<QuicClientEndpoint> {
|
||||||
pub fn new(cert: &str, addr: SocketAddr, host: String, table: (MessageList, MessageList)) -> Result<Self, crate::error::Error> {
|
pub fn new(
|
||||||
|
cert: &str,
|
||||||
|
addr: SocketAddr,
|
||||||
|
host: String,
|
||||||
|
table: (MessageList, MessageList),
|
||||||
|
) -> Result<Self, crate::error::Error> {
|
||||||
let (item_sender, item_receiver) = mpsc::unbounded_channel();
|
let (item_sender, item_receiver) = mpsc::unbounded_channel();
|
||||||
let (event_sender, event_receiver) = mpsc::unbounded_channel();
|
let (event_sender, event_receiver) = mpsc::unbounded_channel();
|
||||||
let (stream_sender, stream_receiver) = mpsc::unbounded_channel();
|
let (stream_sender, stream_receiver) = mpsc::unbounded_channel();
|
||||||
@ -68,13 +76,18 @@ impl QuicRelay<QuicClientEndpoint> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl QuicRelay<QuicServerEndpoint> {
|
impl QuicRelay<QuicServerEndpoint> {
|
||||||
pub fn new(key_path: &str, cert_path: &str, addr: SocketAddr, table: (MessageList, MessageList)) -> Result<Self, crate::error::Error> {
|
pub fn new(
|
||||||
|
key_path: &str,
|
||||||
|
cert_path: &str,
|
||||||
|
addr: SocketAddr,
|
||||||
|
table: (MessageList, MessageList),
|
||||||
|
) -> Result<Self, crate::error::Error> {
|
||||||
let (item_sender, item_receiver) = mpsc::unbounded_channel();
|
let (item_sender, item_receiver) = mpsc::unbounded_channel();
|
||||||
let (event_sender, event_receiver) = mpsc::unbounded_channel();
|
let (event_sender, event_receiver) = mpsc::unbounded_channel();
|
||||||
let (stream_sender, stream_receiver) = mpsc::unbounded_channel();
|
let (stream_sender, stream_receiver) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
Ok(QuicRelay {
|
Ok(QuicRelay {
|
||||||
base: Mutex::new(Some(QuicServerEndpoint::new(key_path, cert_path, &addr )?)),
|
base: Mutex::new(Some(QuicServerEndpoint::new(key_path, cert_path, &addr)?)),
|
||||||
self_id: Arc::new(AtomicU64::new(0)),
|
self_id: Arc::new(AtomicU64::new(0)),
|
||||||
in_table: MessageTable::from(table.0),
|
in_table: MessageTable::from(table.0),
|
||||||
_out_table: MessageTable::from(table.1),
|
_out_table: MessageTable::from(table.1),
|
||||||
@ -88,16 +101,16 @@ impl QuicRelay<QuicServerEndpoint> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> TypeTagAccept for QuicRelay<B>
|
impl<B> TypeTagAccept for QuicRelay<B>
|
||||||
where B: Stream<Item = Connecting> + Send + 'static
|
where
|
||||||
|
B: Stream<Item = Connecting> + Send + 'static,
|
||||||
{
|
{
|
||||||
|
|
||||||
fn iter_types(&self) -> Box<dyn Iterator<Item = (TypeTag, Option<(TypeTag, TypeTag)>)> + '_> {
|
fn iter_types(&self) -> Box<dyn Iterator<Item = (TypeTag, Option<(TypeTag, TypeTag)>)> + '_> {
|
||||||
let iter = self.in_table.iter_types();
|
let iter = self.in_table.iter_types();
|
||||||
Box::new(iter.map(|(x, y)| (x.clone(), y.cloned())))
|
Box::new(iter.map(|(x, y)| (x.clone(), y.cloned())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept_msg(&self, msg: &TypeTag) -> bool{
|
fn accept_msg(&self, msg: &TypeTag) -> bool {
|
||||||
self.in_table.accept_message(msg)
|
self.in_table.accept_message(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,8 +119,9 @@ where B: Stream<Item = Connecting> + Send + 'static
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> SendUntypedReceiver for QuicRelay<B>
|
impl<B> SendUntypedReceiver for QuicRelay<B>
|
||||||
where B: for<'a> WaitIdle<'a> + Stream<Item = Connecting> + Send + 'static
|
where
|
||||||
|
B: for<'a> WaitIdle<'a> + Stream<Item = Connecting> + Send + 'static,
|
||||||
{
|
{
|
||||||
fn send(&self, msg: Action, _bus: &Bus) -> Result<(), messagebus::error::Error<Action>> {
|
fn send(&self, msg: Action, _bus: &Bus) -> Result<(), messagebus::error::Error<Action>> {
|
||||||
match msg {
|
match msg {
|
||||||
@ -129,7 +143,7 @@ impl<B> SendUntypedReceiver for QuicRelay<B>
|
|||||||
let mut body_buff = Vec::new();
|
let mut body_buff = Vec::new();
|
||||||
let mut header_buff = Vec::new();
|
let mut header_buff = Vec::new();
|
||||||
let mut item = None;
|
let mut item = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
println!("begin");
|
println!("begin");
|
||||||
|
|
||||||
@ -144,7 +158,10 @@ impl<B> SendUntypedReceiver for QuicRelay<B>
|
|||||||
let conn = match conn.await {
|
let conn = match conn.await {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("connection dropped with err {}. waiting next connection", err);
|
println!(
|
||||||
|
"connection dropped with err {}. waiting next connection",
|
||||||
|
err
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -163,7 +180,7 @@ impl<B> SendUntypedReceiver for QuicRelay<B>
|
|||||||
conn.connection.close(0u32.into(), b"done");
|
conn.connection.close(0u32.into(), b"done");
|
||||||
incoming.wait_idle().await;
|
incoming.wait_idle().await;
|
||||||
break;
|
break;
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// match tokio::time::timeout(Duration::from_secs(5), rx.recv()).await {
|
// match tokio::time::timeout(Duration::from_secs(5), rx.recv()).await {
|
||||||
@ -189,7 +206,7 @@ impl<B> SendUntypedReceiver for QuicRelay<B>
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
let (mut send, _) = match conn.connection.open_bi().await {
|
let (mut send, _) = match conn.connection.open_bi().await {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -200,7 +217,7 @@ impl<B> SendUntypedReceiver for QuicRelay<B>
|
|||||||
|
|
||||||
body_buff.clear();
|
body_buff.clear();
|
||||||
let pkt = r.serialize(BodyType::Cbor, &mut body_buff).unwrap();
|
let pkt = r.serialize(BodyType::Cbor, &mut body_buff).unwrap();
|
||||||
|
|
||||||
header_buff.resize(16, 0);
|
header_buff.resize(16, 0);
|
||||||
serde_cbor::to_writer(&mut header_buff, &pkt).unwrap();
|
serde_cbor::to_writer(&mut header_buff, &pkt).unwrap();
|
||||||
let body_size = header_buff.len() - 16;
|
let body_size = header_buff.len() - 16;
|
||||||
@ -214,13 +231,19 @@ impl<B> SendUntypedReceiver for QuicRelay<B>
|
|||||||
|
|
||||||
if let Err(err) = send.write_all(&header_buff).await {
|
if let Err(err) = send.write_all(&header_buff).await {
|
||||||
item = Some(r);
|
item = Some(r);
|
||||||
println!("write broken connection err {}. try with next connection", err);
|
println!(
|
||||||
|
"write broken connection err {}. try with next connection",
|
||||||
|
err
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(err) = send.finish().await {
|
if let Err(err) = send.finish().await {
|
||||||
item = Some(r);
|
item = Some(r);
|
||||||
println!("finish broken connection err {}. try with next connection", err);
|
println!(
|
||||||
|
"finish broken connection err {}. try with next connection",
|
||||||
|
err
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,177 +276,215 @@ impl<B> SendUntypedReceiver for QuicRelay<B>
|
|||||||
match msg.as_shared_boxed() {
|
match msg.as_shared_boxed() {
|
||||||
Ok(msg) => {
|
Ok(msg) => {
|
||||||
if let Err(err) = self.item_sender.send(Some((mid, msg, req).into())) {
|
if let Err(err) = self.item_sender.send(Some((mid, msg, req).into())) {
|
||||||
Err(messagebus::error::Error::TryAgain(err.0.unwrap().unwrap_send().unwrap().1.upcast_box()))
|
Err(messagebus::error::Error::TryAgain(
|
||||||
|
err.0.unwrap().unwrap_send().unwrap().1.upcast_box(),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(msg) => Err(messagebus::error::Error::TryAgain(msg)),
|
Err(msg) => Err(messagebus::error::Error::TryAgain(msg)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> ReciveUntypedReceiver for QuicRelay<B>
|
impl<B> ReciveUntypedReceiver for QuicRelay<B>
|
||||||
where B: Send
|
where
|
||||||
|
B: Send,
|
||||||
{
|
{
|
||||||
type Stream = GenericEventStream;
|
type Stream = GenericEventStream;
|
||||||
|
|
||||||
fn event_stream(&self, bus: Bus) -> Self::Stream {
|
fn event_stream(&self, bus: Bus) -> Self::Stream {
|
||||||
let self_id = self.self_id.clone();
|
let self_id = self.self_id.clone();
|
||||||
|
|
||||||
let mut recv_stream = self.stream_receiver.lock().take().unwrap();
|
let mut recv_stream = self.stream_receiver.lock().take().unwrap();
|
||||||
let mut recv_events = self.event_receiver.lock().take().unwrap();
|
let mut recv_events = self.event_receiver.lock().take().unwrap();
|
||||||
let sender = self.item_sender.clone();
|
let sender = self.item_sender.clone();
|
||||||
|
|
||||||
let stream1 = futures::stream::poll_fn(move |cx|recv_stream.poll_recv(cx))
|
let stream1 = futures::stream::poll_fn(move |cx| recv_stream.poll_recv(cx))
|
||||||
.map(move |incoming| {
|
.map(move |incoming| {
|
||||||
let buff: Vec<u8> = Vec::with_capacity(1024);
|
let buff: Vec<u8> = Vec::with_capacity(1024);
|
||||||
let bus = bus.clone();
|
let bus = bus.clone();
|
||||||
let self_id = self_id.clone();
|
let self_id = self_id.clone();
|
||||||
let sender = sender.clone();
|
let sender = sender.clone();
|
||||||
|
|
||||||
futures::stream::unfold((incoming, bus, sender, self_id, buff), |(mut incoming, bus, sender, self_id, mut buff)| async move {
|
futures::stream::unfold(
|
||||||
loop {
|
(incoming, bus, sender, self_id, buff),
|
||||||
let (_, mut recv) = match incoming.next().await? {
|
|(mut incoming, bus, sender, self_id, mut buff)| async move {
|
||||||
Ok(recv) => recv,
|
loop {
|
||||||
Err(err) => {
|
let (_, mut recv) = match incoming.next().await? {
|
||||||
println!("error: {}", err);
|
Ok(recv) => recv,
|
||||||
return None;
|
Err(err) => {
|
||||||
}
|
println!("error: {}", err);
|
||||||
};
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
buff.resize(4, 0);
|
buff.resize(4, 0);
|
||||||
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
||||||
println!("recv err: {}", err);
|
println!("recv err: {}", err);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let verb = match std::str::from_utf8(&buff[0..4]) {
|
|
||||||
Ok(m) => m,
|
|
||||||
Err(err) => {
|
|
||||||
println!("recv err parse: {}", err);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if verb == "PING" {
|
let verb = match std::str::from_utf8(&buff[0..4]) {
|
||||||
println!(">> PING");
|
Ok(m) => m,
|
||||||
continue;
|
Err(err) => {
|
||||||
}
|
println!("recv err parse: {}", err);
|
||||||
|
continue;
|
||||||
if verb != "MBUS" {
|
|
||||||
println!("Not MBUS packet!");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
buff.resize(12, 0);
|
|
||||||
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
|
||||||
println!("recv err: {}", err);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut reader = &buff[..];
|
|
||||||
let version = reader.get_u16();
|
|
||||||
let content_type = reader.get_u16();
|
|
||||||
let body_size = reader.get_u64();
|
|
||||||
|
|
||||||
buff.resize(body_size as _, 0);
|
|
||||||
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
|
||||||
println!("recv err: {}", err);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(recv);
|
|
||||||
|
|
||||||
// println!("inbound packet MBUS v: {}; ct: {}; bs: {}",
|
|
||||||
// version, content_type, body_size);
|
|
||||||
|
|
||||||
let event = match content_type {
|
|
||||||
0 => { // CBOR
|
|
||||||
let proto: ProtocolPacket = match serde_cbor::from_slice(&buff[..]) {
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(err) => {
|
|
||||||
println!("pkt parse err: {}", err);
|
|
||||||
continue;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let item: ProtocolItem = match proto.deserialize(&bus) {
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(err) => {
|
|
||||||
println!("item parse err: {}", err);
|
|
||||||
continue;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
match item {
|
|
||||||
ProtocolItem::Event(ev) => ev.map_msg(|msg|msg.upcast_box()),
|
|
||||||
ProtocolItem::Action(action) => {
|
|
||||||
match action {
|
|
||||||
Action::Close => {
|
|
||||||
println!("warning: Close recevied - ignoring!");
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::Exited))).unwrap();
|
|
||||||
},
|
|
||||||
Action::Flush => {
|
|
||||||
println!("flush");
|
|
||||||
bus.flush().await;
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::Flushed))).unwrap();
|
|
||||||
},
|
|
||||||
Action::Sync => {
|
|
||||||
println!("flush");
|
|
||||||
bus.sync().await;
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::Synchronized(Ok(()))))).unwrap();
|
|
||||||
},
|
|
||||||
Action::Init(..) => (),
|
|
||||||
Action::Stats => (),
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ProtocolItem::Send(mid, msg, req) => {
|
|
||||||
let self_id = self_id.clone();
|
|
||||||
let sender = sender.clone();
|
|
||||||
let bus = bus.clone();
|
|
||||||
|
|
||||||
let _ = tokio::spawn(async move {
|
|
||||||
if req {
|
|
||||||
let res = bus.request_boxed(
|
|
||||||
msg.upcast_box(),
|
|
||||||
SendOptions::Except(self_id.load(Ordering::SeqCst))
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|x|x.as_shared_boxed().unwrap())
|
|
||||||
.map_err(|x|x.map_msg(|_|()));
|
|
||||||
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::Response(mid, res)))).unwrap();
|
|
||||||
} else {
|
|
||||||
let tt = msg.type_tag();
|
|
||||||
let _ = bus.send_boxed(msg.upcast_box(), Default::default())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::BatchComplete(tt, 1)))).unwrap();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_ => unimplemented!()
|
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
_ => unimplemented!()
|
|
||||||
};
|
|
||||||
|
|
||||||
return Some((event, (incoming, bus, sender, self_id, buff)));
|
if verb == "PING" {
|
||||||
}
|
println!(">> PING");
|
||||||
})
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if verb != "MBUS" {
|
||||||
|
println!("Not MBUS packet!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buff.resize(12, 0);
|
||||||
|
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
||||||
|
println!("recv err: {}", err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut reader = &buff[..];
|
||||||
|
let version = reader.get_u16();
|
||||||
|
let content_type = reader.get_u16();
|
||||||
|
let body_size = reader.get_u64();
|
||||||
|
|
||||||
|
buff.resize(body_size as _, 0);
|
||||||
|
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
||||||
|
println!("recv err: {}", err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(recv);
|
||||||
|
|
||||||
|
// println!("inbound packet MBUS v: {}; ct: {}; bs: {}",
|
||||||
|
// version, content_type, body_size);
|
||||||
|
|
||||||
|
let event = match content_type {
|
||||||
|
0 => {
|
||||||
|
// CBOR
|
||||||
|
let proto: ProtocolPacket =
|
||||||
|
match serde_cbor::from_slice(&buff[..]) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => {
|
||||||
|
println!("pkt parse err: {}", err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item: ProtocolItem = match proto.deserialize(&bus) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => {
|
||||||
|
println!("item parse err: {}", err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match item {
|
||||||
|
ProtocolItem::Event(ev) => {
|
||||||
|
ev.map_msg(|msg| msg.upcast_box())
|
||||||
|
}
|
||||||
|
ProtocolItem::Action(action) => {
|
||||||
|
match action {
|
||||||
|
Action::Close => {
|
||||||
|
println!("warning: Close recevied - ignoring!");
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::Exited,
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Action::Flush => {
|
||||||
|
println!("flush");
|
||||||
|
bus.flush_all().await;
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::Flushed,
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Action::Sync => {
|
||||||
|
println!("flush");
|
||||||
|
bus.sync_all().await;
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::Synchronized(Ok(())),
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Action::Init(..) => (),
|
||||||
|
Action::Stats => (),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ProtocolItem::Send(mid, msg, req) => {
|
||||||
|
let self_id = self_id.clone();
|
||||||
|
let sender = sender.clone();
|
||||||
|
let bus = bus.clone();
|
||||||
|
|
||||||
|
let _ = tokio::spawn(async move {
|
||||||
|
if req {
|
||||||
|
let res = bus
|
||||||
|
.request_boxed(
|
||||||
|
msg.upcast_box(),
|
||||||
|
SendOptions::Except(
|
||||||
|
self_id.load(Ordering::SeqCst),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|x| x.as_shared_boxed().unwrap())
|
||||||
|
.map_err(|x| x.map_msg(|_| ()));
|
||||||
|
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::Response(mid, res),
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
let tt = msg.type_tag();
|
||||||
|
let _ = bus
|
||||||
|
.send_boxed(
|
||||||
|
msg.upcast_box(),
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::BatchComplete(tt, 1),
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Some((event, (incoming, bus, sender, self_id, buff)));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.flatten();
|
.flatten();
|
||||||
|
|
||||||
let stream2 = futures::stream::poll_fn(move |cx|recv_events.poll_recv(cx));
|
let stream2 = futures::stream::poll_fn(move |cx| recv_events.poll_recv(cx));
|
||||||
Box::pin(
|
Box::pin(
|
||||||
futures::stream::select(stream1, stream2)
|
futures::stream::select(stream1, stream2)
|
||||||
.take_while(|x| futures::future::ready(!matches!(x, Event::Exited)))
|
.take_while(|x| futures::future::ready(!matches!(x, Event::Exited))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use bytes::{Buf, BufMut};
|
use bytes::{Buf, BufMut};
|
||||||
use futures::{Stream, StreamExt, pin_mut};
|
|
||||||
use futures::stream::unfold;
|
use futures::stream::unfold;
|
||||||
use messagebus::{Action, Bus, Event, EventBoxed, Message, ReciveUntypedReceiver, SendOptions, SendUntypedReceiver, TypeTag, TypeTagAccept};
|
use futures::{pin_mut, Stream, StreamExt};
|
||||||
use messagebus::error::GenericError;
|
use messagebus::error::GenericError;
|
||||||
|
use messagebus::{
|
||||||
|
Action, Bus, Event, EventBoxed, Message, ReciveUntypedReceiver, SendOptions,
|
||||||
|
SendUntypedReceiver, TypeTag, TypeTagAccept,
|
||||||
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
|
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
|
||||||
@ -17,15 +20,13 @@ use crate::proto::{BodyType, ProtocolItem, ProtocolPacket};
|
|||||||
|
|
||||||
use super::{GenericEventStream, MessageList, MessageTable};
|
use super::{GenericEventStream, MessageList, MessageTable};
|
||||||
|
|
||||||
|
|
||||||
pub struct TcpRelay {
|
pub struct TcpRelay {
|
||||||
server_mode: bool,
|
server_mode: bool,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
|
|
||||||
self_id: Arc<AtomicU64>,
|
self_id: Arc<AtomicU64>,
|
||||||
in_table: MessageTable,
|
in_table: MessageTable,
|
||||||
// _out_table: MessageTable,
|
// _out_table: MessageTable,
|
||||||
|
|
||||||
item_sender: UnboundedSender<Option<ProtocolItem>>,
|
item_sender: UnboundedSender<Option<ProtocolItem>>,
|
||||||
item_receiver: Mutex<Option<UnboundedReceiver<Option<ProtocolItem>>>>,
|
item_receiver: Mutex<Option<UnboundedReceiver<Option<ProtocolItem>>>>,
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ impl TcpRelay {
|
|||||||
let (item_sender, item_receiver) = mpsc::unbounded_channel();
|
let (item_sender, item_receiver) = mpsc::unbounded_channel();
|
||||||
let (event_sender, event_receiver) = mpsc::unbounded_channel();
|
let (event_sender, event_receiver) = mpsc::unbounded_channel();
|
||||||
let (stream_sender, stream_receiver) = mpsc::unbounded_channel();
|
let (stream_sender, stream_receiver) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
self_id: Arc::new(AtomicU64::new(0)),
|
self_id: Arc::new(AtomicU64::new(0)),
|
||||||
server_mode,
|
server_mode,
|
||||||
@ -56,65 +57,66 @@ impl TcpRelay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connections(&self) -> impl Stream<Item = TcpRelayConnection> {
|
fn connections(&self) -> impl Stream<Item = TcpRelayConnection> {
|
||||||
unfold((self.server_mode, self.addr), move |(sm, addr)| async move {
|
unfold(
|
||||||
let stream = if sm {
|
(self.server_mode, self.addr),
|
||||||
let bind_res = TcpListener::bind(addr).await;
|
move |(sm, addr)| async move {
|
||||||
let listener = match bind_res {
|
let stream = if sm {
|
||||||
Err(err) => {
|
let bind_res = TcpListener::bind(addr).await;
|
||||||
println!("bind error: {}", err);
|
let listener = match bind_res {
|
||||||
return None;
|
Err(err) => {
|
||||||
}
|
println!("bind error: {}", err);
|
||||||
|
return None;
|
||||||
Ok(listener) => listener,
|
}
|
||||||
|
|
||||||
|
Ok(listener) => listener,
|
||||||
|
};
|
||||||
|
|
||||||
|
unfold((listener,), move |(listener,)| async move {
|
||||||
|
let (stream, _addr) = match listener.accept().await {
|
||||||
|
Err(err) => {
|
||||||
|
println!("accept error: {}", err);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(listener) => listener,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((TcpRelayConnection::from(stream), (listener,)))
|
||||||
|
})
|
||||||
|
.left_stream()
|
||||||
|
} else {
|
||||||
|
unfold((addr,), move |(addr,)| async move {
|
||||||
|
let stream = match TcpStream::connect(addr).await {
|
||||||
|
Err(err) => {
|
||||||
|
println!("connect error: {}", err);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(listener) => listener,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((TcpRelayConnection::from(stream), (addr,)))
|
||||||
|
})
|
||||||
|
.right_stream()
|
||||||
};
|
};
|
||||||
|
|
||||||
unfold((listener, ), move |(listener, )| async move {
|
Some((stream, (sm, addr)))
|
||||||
let (stream, _addr) = match listener.accept().await {
|
},
|
||||||
Err(err) => {
|
)
|
||||||
println!("accept error: {}", err);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(listener) => listener,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some((TcpRelayConnection::from(stream), (listener, )))
|
|
||||||
}).left_stream()
|
|
||||||
} else {
|
|
||||||
unfold((addr, ), move |(addr, )| async move {
|
|
||||||
let stream = match TcpStream::connect(addr).await {
|
|
||||||
Err(err) => {
|
|
||||||
println!("connect error: {}", err);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(listener) => listener,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some((TcpRelayConnection::from(stream), (addr, )))
|
|
||||||
}).right_stream()
|
|
||||||
};
|
|
||||||
|
|
||||||
Some((stream, (sm, addr)))
|
|
||||||
})
|
|
||||||
.flatten()
|
.flatten()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct TcpRelayConnection {
|
struct TcpRelayConnection {
|
||||||
recv: OwnedReadHalf,
|
recv: OwnedReadHalf,
|
||||||
send: OwnedWriteHalf,
|
send: OwnedWriteHalf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TcpStream> for TcpRelayConnection {
|
impl From<TcpStream> for TcpRelayConnection {
|
||||||
fn from(stream: TcpStream) -> Self {
|
fn from(stream: TcpStream) -> Self {
|
||||||
let (recv, send) = stream.into_split();
|
let (recv, send) = stream.into_split();
|
||||||
TcpRelayConnection {
|
TcpRelayConnection { recv, send }
|
||||||
recv,
|
|
||||||
send
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +126,7 @@ impl TypeTagAccept for TcpRelay {
|
|||||||
Box::new(iter.map(|(x, y)| (x.clone(), y.cloned())))
|
Box::new(iter.map(|(x, y)| (x.clone(), y.cloned())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept_msg(&self, msg: &TypeTag) -> bool{
|
fn accept_msg(&self, msg: &TypeTag) -> bool {
|
||||||
self.in_table.accept_message(msg)
|
self.in_table.accept_message(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +156,7 @@ impl SendUntypedReceiver for TcpRelay {
|
|||||||
let mut body_buff = Vec::new();
|
let mut body_buff = Vec::new();
|
||||||
let mut header_buff = Vec::new();
|
let mut header_buff = Vec::new();
|
||||||
let mut item = None;
|
let mut item = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
println!("begin");
|
println!("begin");
|
||||||
|
|
||||||
@ -179,13 +181,13 @@ impl SendUntypedReceiver for TcpRelay {
|
|||||||
println!("closing");
|
println!("closing");
|
||||||
drop(conn.send);
|
drop(conn.send);
|
||||||
break;
|
break;
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
body_buff.clear();
|
body_buff.clear();
|
||||||
let pkt = r.serialize(BodyType::Cbor, &mut body_buff).unwrap();
|
let pkt = r.serialize(BodyType::Cbor, &mut body_buff).unwrap();
|
||||||
|
|
||||||
header_buff.resize(16, 0);
|
header_buff.resize(16, 0);
|
||||||
serde_cbor::to_writer(&mut header_buff, &pkt).unwrap();
|
serde_cbor::to_writer(&mut header_buff, &pkt).unwrap();
|
||||||
let body_size = header_buff.len() - 16;
|
let body_size = header_buff.len() - 16;
|
||||||
@ -199,7 +201,10 @@ impl SendUntypedReceiver for TcpRelay {
|
|||||||
|
|
||||||
if let Err(err) = conn.send.write_all(&header_buff).await {
|
if let Err(err) = conn.send.write_all(&header_buff).await {
|
||||||
item = Some(r);
|
item = Some(r);
|
||||||
println!("write broken connection err {}. try with next connection", err);
|
println!(
|
||||||
|
"write broken connection err {}. try with next connection",
|
||||||
|
err
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,12 +237,14 @@ impl SendUntypedReceiver for TcpRelay {
|
|||||||
match msg.as_shared_boxed() {
|
match msg.as_shared_boxed() {
|
||||||
Ok(msg) => {
|
Ok(msg) => {
|
||||||
if let Err(err) = self.item_sender.send(Some((mid, msg, req).into())) {
|
if let Err(err) = self.item_sender.send(Some((mid, msg, req).into())) {
|
||||||
Err(messagebus::error::Error::TryAgain(err.0.unwrap().unwrap_send().unwrap().1.upcast_box()))
|
Err(messagebus::error::Error::TryAgain(
|
||||||
|
err.0.unwrap().unwrap_send().unwrap().1.upcast_box(),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(msg) => Err(messagebus::error::Error::TryAgain(msg)),
|
Err(msg) => Err(messagebus::error::Error::TryAgain(msg)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,141 +255,176 @@ impl ReciveUntypedReceiver for TcpRelay {
|
|||||||
|
|
||||||
fn event_stream(&self, bus: Bus) -> Self::Stream {
|
fn event_stream(&self, bus: Bus) -> Self::Stream {
|
||||||
let self_id = self.self_id.clone();
|
let self_id = self.self_id.clone();
|
||||||
|
|
||||||
let mut recv_stream = self.stream_receiver.lock().take().unwrap();
|
let mut recv_stream = self.stream_receiver.lock().take().unwrap();
|
||||||
let mut recv_events = self.event_receiver.lock().take().unwrap();
|
let mut recv_events = self.event_receiver.lock().take().unwrap();
|
||||||
let sender = self.item_sender.clone();
|
let sender = self.item_sender.clone();
|
||||||
|
|
||||||
let stream1 = futures::stream::poll_fn(move |cx|recv_stream.poll_recv(cx))
|
let stream1 = futures::stream::poll_fn(move |cx| recv_stream.poll_recv(cx))
|
||||||
.map(move |incoming| {
|
.map(move |incoming| {
|
||||||
let buff: Vec<u8> = Vec::with_capacity(1024);
|
let buff: Vec<u8> = Vec::with_capacity(1024);
|
||||||
let bus = bus.clone();
|
let bus = bus.clone();
|
||||||
let self_id = self_id.clone();
|
let self_id = self_id.clone();
|
||||||
let sender = sender.clone();
|
let sender = sender.clone();
|
||||||
|
|
||||||
futures::stream::unfold((incoming, bus, sender, self_id, buff), |(mut recv, bus, sender, self_id, mut buff)| async move {
|
futures::stream::unfold(
|
||||||
loop {
|
(incoming, bus, sender, self_id, buff),
|
||||||
buff.resize(4, 0);
|
|(mut recv, bus, sender, self_id, mut buff)| async move {
|
||||||
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
loop {
|
||||||
println!("recv err: {}", err);
|
buff.resize(4, 0);
|
||||||
break None;
|
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
||||||
}
|
println!("recv err: {}", err);
|
||||||
|
break None;
|
||||||
|
}
|
||||||
|
|
||||||
if &buff == b"PING" {
|
if &buff == b"PING" {
|
||||||
println!(">> PING");
|
println!(">> PING");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if &buff != b"MBUS" {
|
if &buff != b"MBUS" {
|
||||||
println!("Not MBUS packet!");
|
println!("Not MBUS packet!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
buff.resize(12, 0);
|
buff.resize(12, 0);
|
||||||
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
||||||
println!("recv err: {}", err);
|
println!("recv err: {}", err);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut reader = &buff[..];
|
let mut reader = &buff[..];
|
||||||
let version = reader.get_u16();
|
let version = reader.get_u16();
|
||||||
let content_type = reader.get_u16();
|
let content_type = reader.get_u16();
|
||||||
let body_size = reader.get_u64();
|
let body_size = reader.get_u64();
|
||||||
|
|
||||||
buff.resize(body_size as _, 0);
|
buff.resize(body_size as _, 0);
|
||||||
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
if let Err(err) = recv.read_exact(&mut buff[..]).await {
|
||||||
println!("recv err: {}", err);
|
println!("recv err: {}", err);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// println!("inbound packet MBUS v: {}; ct: {}; bs: {}",
|
// println!("inbound packet MBUS v: {}; ct: {}; bs: {}",
|
||||||
// version, content_type, body_size);
|
// version, content_type, body_size);
|
||||||
|
|
||||||
let event = match content_type {
|
let event = match content_type {
|
||||||
0 => { // CBOR
|
0 => {
|
||||||
let proto: ProtocolPacket = match serde_cbor::from_slice(&buff[..]) {
|
// CBOR
|
||||||
Ok(val) => val,
|
let proto: ProtocolPacket =
|
||||||
Err(err) => {
|
match serde_cbor::from_slice(&buff[..]) {
|
||||||
println!("pkt parse err: {}", err);
|
Ok(val) => val,
|
||||||
continue;
|
Err(err) => {
|
||||||
},
|
println!("pkt parse err: {}", err);
|
||||||
};
|
continue;
|
||||||
|
|
||||||
let item: ProtocolItem = match proto.deserialize(&bus) {
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(err) => {
|
|
||||||
println!("item parse err: {}", err);
|
|
||||||
continue;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
match item {
|
|
||||||
ProtocolItem::Event(ev) => ev.map_msg(|msg|msg.upcast_box()),
|
|
||||||
ProtocolItem::Action(action) => {
|
|
||||||
match action {
|
|
||||||
Action::Close => {
|
|
||||||
println!("warning: Close recevied - ignoring!");
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::Exited))).unwrap();
|
|
||||||
},
|
|
||||||
Action::Flush => {
|
|
||||||
println!("flush");
|
|
||||||
bus.flush().await;
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::Flushed))).unwrap();
|
|
||||||
},
|
|
||||||
Action::Sync => {
|
|
||||||
println!("sync");
|
|
||||||
bus.sync().await;
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::Synchronized(Ok(()))))).unwrap();
|
|
||||||
},
|
|
||||||
Action::Init(..) => (),
|
|
||||||
Action::Stats => (),
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ProtocolItem::Send(mid, msg, req) => {
|
|
||||||
let self_id = self_id.clone();
|
|
||||||
let sender = sender.clone();
|
|
||||||
let bus = bus.clone();
|
|
||||||
|
|
||||||
let _ = tokio::spawn(async move {
|
|
||||||
if req {
|
|
||||||
let res = bus.request_boxed(
|
|
||||||
msg.upcast_box(),
|
|
||||||
SendOptions::Except(self_id.load(Ordering::SeqCst))
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|x|x.as_shared_boxed().unwrap())
|
|
||||||
.map_err(|x|x.map_msg(|_|()));
|
|
||||||
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::Response(mid, res)))).unwrap();
|
|
||||||
} else {
|
|
||||||
let tt = msg.type_tag();
|
|
||||||
let _ = bus.send_boxed(msg.upcast_box(), Default::default())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
sender.send(Some(ProtocolItem::Event(Event::BatchComplete(tt, 1)))).unwrap();
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
continue;
|
let item: ProtocolItem = match proto.deserialize(&bus) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => {
|
||||||
|
println!("item parse err: {}", err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match item {
|
||||||
|
ProtocolItem::Event(ev) => {
|
||||||
|
ev.map_msg(|msg| msg.upcast_box())
|
||||||
|
}
|
||||||
|
ProtocolItem::Action(action) => {
|
||||||
|
match action {
|
||||||
|
Action::Close => {
|
||||||
|
println!("warning: Close recevied - ignoring!");
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::Exited,
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Action::Flush => {
|
||||||
|
println!("flush");
|
||||||
|
bus.flush_all().await;
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::Flushed,
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Action::Sync => {
|
||||||
|
println!("sync");
|
||||||
|
bus.sync_all().await;
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::Synchronized(Ok(())),
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Action::Init(..) => (),
|
||||||
|
Action::Stats => (),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ProtocolItem::Send(mid, msg, req) => {
|
||||||
|
let self_id = self_id.clone();
|
||||||
|
let sender = sender.clone();
|
||||||
|
let bus = bus.clone();
|
||||||
|
|
||||||
|
let _ = tokio::spawn(async move {
|
||||||
|
if req {
|
||||||
|
let res = bus
|
||||||
|
.request_boxed(
|
||||||
|
msg.upcast_box(),
|
||||||
|
SendOptions::Except(
|
||||||
|
self_id.load(Ordering::SeqCst),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|x| x.as_shared_boxed().unwrap())
|
||||||
|
.map_err(|x| x.map_msg(|_| ()));
|
||||||
|
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::Response(mid, res),
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
let tt = msg.type_tag();
|
||||||
|
let _ = bus
|
||||||
|
.send_boxed(
|
||||||
|
msg.upcast_box(),
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
sender
|
||||||
|
.send(Some(ProtocolItem::Event(
|
||||||
|
Event::BatchComplete(tt, 1),
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
_ => unimplemented!()
|
|
||||||
}
|
}
|
||||||
},
|
_ => unimplemented!(),
|
||||||
_ => unimplemented!()
|
};
|
||||||
};
|
|
||||||
|
|
||||||
return Some((event, (recv, bus, sender, self_id, buff)));
|
return Some((event, (recv, bus, sender, self_id, buff)));
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.flatten();
|
.flatten();
|
||||||
|
|
||||||
let stream2 = futures::stream::poll_fn(move |cx|recv_events.poll_recv(cx));
|
let stream2 = futures::stream::poll_fn(move |cx| recv_events.poll_recv(cx));
|
||||||
Box::pin(
|
Box::pin(
|
||||||
futures::stream::select(stream1, stream2)
|
futures::stream::select(stream1, stream2)
|
||||||
.take_while(|x| futures::future::ready(!matches!(x, Event::Exited)))
|
.take_while(|x| futures::future::ready(!matches!(x, Event::Exited))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ async fn iter(bus: &Bus) {
|
|||||||
bus.send(MsgF32(0.)).await.unwrap();
|
bus.send(MsgF32(0.)).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
bus.flush().await;
|
bus.flush_all().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
@ -156,7 +156,7 @@ async fn main() {
|
|||||||
println!("Avg time: {:.4}", time_sum as f64 / (count as f64 * 1000.0));
|
println!("Avg time: {:.4}", time_sum as f64 / (count as f64 * 1000.0));
|
||||||
|
|
||||||
println!("flush");
|
println!("flush");
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
println!("close");
|
println!("close");
|
||||||
b.close().await;
|
b.close().await;
|
||||||
|
@ -187,7 +187,7 @@ async fn main() {
|
|||||||
b.send(MsgF32(0.)).await.unwrap();
|
b.send(MsgF32(0.)).await.unwrap();
|
||||||
|
|
||||||
println!("flush");
|
println!("flush");
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
println!("close");
|
println!("close");
|
||||||
b.close().await;
|
b.close().await;
|
||||||
|
@ -190,7 +190,7 @@ async fn main() {
|
|||||||
b.send(MsgF32(0f32)).await.unwrap();
|
b.send(MsgF32(0f32)).await.unwrap();
|
||||||
println!("flush");
|
println!("flush");
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
println!("sending boxed variant");
|
println!("sending boxed variant");
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ async fn main() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
println!("flush");
|
println!("flush");
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
println!("close");
|
println!("close");
|
||||||
b.close().await;
|
b.close().await;
|
||||||
|
@ -45,7 +45,7 @@ async fn main() {
|
|||||||
// b.
|
// b.
|
||||||
|
|
||||||
println!("flush");
|
println!("flush");
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
println!("close");
|
println!("close");
|
||||||
b.close().await;
|
b.close().await;
|
||||||
|
@ -80,7 +80,7 @@ async fn main() {
|
|||||||
b.send(MsgU32(32u32)).await.unwrap();
|
b.send(MsgU32(32u32)).await.unwrap();
|
||||||
|
|
||||||
println!("flush");
|
println!("flush");
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
println!("close");
|
println!("close");
|
||||||
b.close().await;
|
b.close().await;
|
||||||
|
@ -81,7 +81,7 @@ async fn main() {
|
|||||||
b.send(MsgI16(7i16)).await.unwrap();
|
b.send(MsgI16(7i16)).await.unwrap();
|
||||||
|
|
||||||
println!("flush");
|
println!("flush");
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
println!("close");
|
println!("close");
|
||||||
b.close().await;
|
b.close().await;
|
||||||
|
@ -83,7 +83,7 @@ async fn main() {
|
|||||||
|
|
||||||
println!("flush");
|
println!("flush");
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
println!("closing");
|
println!("closing");
|
||||||
|
|
||||||
|
182
src/lib.rs
182
src/lib.rs
@ -9,10 +9,9 @@ mod stats;
|
|||||||
mod trait_object;
|
mod trait_object;
|
||||||
pub mod type_tag;
|
pub mod type_tag;
|
||||||
|
|
||||||
|
|
||||||
pub mod __reexport {
|
pub mod __reexport {
|
||||||
pub use serde;
|
|
||||||
pub use ctor;
|
pub use ctor;
|
||||||
|
pub use serde;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -29,7 +28,10 @@ use core::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{collections::{HashMap, HashSet}, sync::Arc};
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use builder::BusBuilder;
|
use builder::BusBuilder;
|
||||||
@ -39,6 +41,7 @@ use stats::Stats;
|
|||||||
|
|
||||||
// public
|
// public
|
||||||
pub use builder::Module;
|
pub use builder::Module;
|
||||||
|
pub use ctor;
|
||||||
pub use envelop::{IntoBoxedMessage, Message, MessageBounds, SharedMessage, TypeTag, TypeTagged};
|
pub use envelop::{IntoBoxedMessage, Message, MessageBounds, SharedMessage, TypeTag, TypeTagged};
|
||||||
pub use handler::*;
|
pub use handler::*;
|
||||||
pub use receiver::{
|
pub use receiver::{
|
||||||
@ -46,8 +49,7 @@ pub use receiver::{
|
|||||||
SendUntypedReceiver, TypeTagAccept,
|
SendUntypedReceiver, TypeTagAccept,
|
||||||
};
|
};
|
||||||
pub use relay::Relay;
|
pub use relay::Relay;
|
||||||
pub use ctor;
|
pub use type_tag::{deserialize_shared_message, register_shared_message};
|
||||||
pub use type_tag::{register_shared_message, deserialize_shared_message};
|
|
||||||
pub type Untyped = Arc<dyn Any + Send + Sync>;
|
pub type Untyped = Arc<dyn Any + Send + Sync>;
|
||||||
|
|
||||||
type LookupQuery = (TypeTag, Option<TypeTag>, Option<TypeTag>);
|
type LookupQuery = (TypeTag, Option<TypeTag>, Option<TypeTag>);
|
||||||
@ -77,26 +79,28 @@ pub struct BusInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BusInner {
|
impl BusInner {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(receivers: HashSet<Receiver>) -> Self {
|
||||||
receivers: HashSet<Receiver>,
|
|
||||||
) -> Self {
|
|
||||||
let mut lookup = HashMap::new();
|
let mut lookup = HashMap::new();
|
||||||
for recv in receivers.iter() {
|
for recv in receivers.iter() {
|
||||||
for (msg, resp) in recv.iter_types() {
|
for (msg, resp) in recv.iter_types() {
|
||||||
lookup.entry((msg.clone(), None, None))
|
lookup
|
||||||
|
.entry((msg.clone(), None, None))
|
||||||
.or_insert_with(HashSet::new)
|
.or_insert_with(HashSet::new)
|
||||||
.insert(recv.clone());
|
.insert(recv.clone());
|
||||||
|
|
||||||
if let Some((resp, err)) = resp {
|
if let Some((resp, err)) = resp {
|
||||||
lookup.entry((msg.clone(), Some(resp.clone()), None))
|
lookup
|
||||||
|
.entry((msg.clone(), Some(resp.clone()), None))
|
||||||
.or_insert_with(HashSet::new)
|
.or_insert_with(HashSet::new)
|
||||||
.insert(recv.clone());
|
.insert(recv.clone());
|
||||||
|
|
||||||
lookup.entry((msg.clone(), None, Some(err.clone())))
|
lookup
|
||||||
|
.entry((msg.clone(), None, Some(err.clone())))
|
||||||
.or_insert_with(HashSet::new)
|
.or_insert_with(HashSet::new)
|
||||||
.insert(recv.clone());
|
.insert(recv.clone());
|
||||||
|
|
||||||
lookup.entry((msg, Some(resp), Some(err)))
|
lookup
|
||||||
|
.entry((msg, Some(resp), Some(err)))
|
||||||
.or_insert_with(HashSet::new)
|
.or_insert_with(HashSet::new)
|
||||||
.insert(recv.clone());
|
.insert(recv.clone());
|
||||||
}
|
}
|
||||||
@ -157,7 +161,7 @@ impl Bus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn flush(&self) {
|
pub async fn flush_all(&self) {
|
||||||
let _handle = self.inner.maintain.lock().await;
|
let _handle = self.inner.maintain.lock().await;
|
||||||
let fuse_count = 32i32;
|
let fuse_count = 32i32;
|
||||||
let mut breaked = false;
|
let mut breaked = false;
|
||||||
@ -189,7 +193,80 @@ impl Bus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sync(&self) {
|
pub async fn flush<M: Message>(&self) {
|
||||||
|
let _handle = self.inner.maintain.lock().await;
|
||||||
|
let fuse_count = 32i32;
|
||||||
|
let mut breaked = false;
|
||||||
|
let mut iters = 0usize;
|
||||||
|
|
||||||
|
for _ in 0..fuse_count {
|
||||||
|
let receivers =
|
||||||
|
self.select_receivers(M::type_tag_(), Default::default(), None, None, false);
|
||||||
|
iters += 1;
|
||||||
|
let mut flushed = false;
|
||||||
|
for r in receivers {
|
||||||
|
if r.need_flush() {
|
||||||
|
flushed = true;
|
||||||
|
|
||||||
|
r.flush(self).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !flushed {
|
||||||
|
breaked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !breaked {
|
||||||
|
warn!(
|
||||||
|
"!!! WARNING: unable to reach equilibrium in {} iterations !!!",
|
||||||
|
fuse_count
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
info!("flushed in {} iterations !!!", iters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn flush2<M1: Message, M2: Message>(&self) {
|
||||||
|
let _handle = self.inner.maintain.lock().await;
|
||||||
|
let fuse_count = 32i32;
|
||||||
|
let mut breaked = false;
|
||||||
|
let mut iters = 0usize;
|
||||||
|
for _ in 0..fuse_count {
|
||||||
|
let receivers1 =
|
||||||
|
self.select_receivers(M1::type_tag_(), Default::default(), None, None, false);
|
||||||
|
|
||||||
|
let receivers2 =
|
||||||
|
self.select_receivers(M2::type_tag_(), Default::default(), None, None, false);
|
||||||
|
|
||||||
|
iters += 1;
|
||||||
|
let mut flushed = false;
|
||||||
|
for r in receivers1.chain(receivers2) {
|
||||||
|
if r.need_flush() {
|
||||||
|
flushed = true;
|
||||||
|
|
||||||
|
r.flush(self).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !flushed {
|
||||||
|
breaked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !breaked {
|
||||||
|
warn!(
|
||||||
|
"!!! WARNING: unable to reach equilibrium in {} iterations !!!",
|
||||||
|
fuse_count
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
info!("flushed in {} iterations !!!", iters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn sync_all(&self) {
|
||||||
let _handle = self.inner.maintain.lock().await;
|
let _handle = self.inner.maintain.lock().await;
|
||||||
|
|
||||||
for r in self.inner.receivers.iter() {
|
for r in self.inner.receivers.iter() {
|
||||||
@ -197,12 +274,45 @@ impl Bus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
pub async fn sync<M: Message>(&self) {
|
||||||
pub async fn flush_and_sync(&self) {
|
let _handle = self.inner.maintain.lock().await;
|
||||||
self.flush().await;
|
let receivers =
|
||||||
self.sync().await;
|
self.select_receivers(M::type_tag_(), Default::default(), None, None, false);
|
||||||
|
|
||||||
|
for r in receivers {
|
||||||
|
r.sync(self).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn sync2<M1: Message, M2: Message>(&self) {
|
||||||
|
let _handle = self.inner.maintain.lock().await;
|
||||||
|
|
||||||
|
let receivers1 =
|
||||||
|
self.select_receivers(M1::type_tag_(), Default::default(), None, None, false);
|
||||||
|
|
||||||
|
let receivers2 =
|
||||||
|
self.select_receivers(M2::type_tag_(), Default::default(), None, None, false);
|
||||||
|
|
||||||
|
for r in receivers1.chain(receivers2) {
|
||||||
|
r.sync(self).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub async fn flush_and_sync_all(&self) {
|
||||||
|
self.flush_all().await;
|
||||||
|
self.sync_all().await;
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub async fn flush_and_sync<M: Message>(&self) {
|
||||||
|
self.flush::<M>().await;
|
||||||
|
self.sync::<M>().await;
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub async fn flush_and_sync2<M1: Message, M2: Message>(&self) {
|
||||||
|
self.flush2::<M1, M2>().await;
|
||||||
|
self.sync2::<M1, M2>().await;
|
||||||
|
}
|
||||||
fn try_reserve(&self, tt: &TypeTag, rs: &[Receiver]) -> Option<SmallVec<[Permit; 32]>> {
|
fn try_reserve(&self, tt: &TypeTag, rs: &[Receiver]) -> Option<SmallVec<[Permit; 32]>> {
|
||||||
let mut permits = SmallVec::<[Permit; 32]>::new();
|
let mut permits = SmallVec::<[Permit; 32]>::new();
|
||||||
|
|
||||||
@ -362,8 +472,11 @@ impl Bus {
|
|||||||
let tt = msg.type_tag();
|
let tt = msg.type_tag();
|
||||||
let mid = ID_COUNTER.fetch_add(1, Ordering::Relaxed);
|
let mid = ID_COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
if let Some(rs) = self.inner.lookup.get(&(msg.type_tag(), None, None))
|
if let Some(rs) = self
|
||||||
.and_then(|rs| rs.first())
|
.inner
|
||||||
|
.lookup
|
||||||
|
.get(&(msg.type_tag(), None, None))
|
||||||
|
.and_then(|rs| rs.first())
|
||||||
{
|
{
|
||||||
let permits = if let Some(x) = rs.try_reserve(&tt) {
|
let permits = if let Some(x) = rs.try_reserve(&tt) {
|
||||||
x
|
x
|
||||||
@ -385,8 +498,11 @@ impl Bus {
|
|||||||
let tt = msg.type_tag();
|
let tt = msg.type_tag();
|
||||||
let mid = ID_COUNTER.fetch_add(1, Ordering::Relaxed);
|
let mid = ID_COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
if let Some(rs) = self.inner.lookup.get(&(msg.type_tag(), None, None))
|
if let Some(rs) = self
|
||||||
.and_then(|rs| rs.first())
|
.inner
|
||||||
|
.lookup
|
||||||
|
.get(&(msg.type_tag(), None, None))
|
||||||
|
.and_then(|rs| rs.first())
|
||||||
{
|
{
|
||||||
Ok(rs.send(self, mid, msg, false, rs.reserve(&tt).await)?)
|
Ok(rs.send(self, mid, msg, false, rs.reserve(&tt).await)?)
|
||||||
} else {
|
} else {
|
||||||
@ -593,11 +709,14 @@ impl Bus {
|
|||||||
|
|
||||||
let mid = ID_COUNTER.fetch_add(1, Ordering::Relaxed);
|
let mid = ID_COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
if let Some(rs) = self.inner.lookup.get(&(tt.clone(), None, None))
|
if let Some(rs) = self
|
||||||
.and_then(|rs| rs.first()) {
|
.inner
|
||||||
|
.lookup
|
||||||
|
.get(&(tt.clone(), None, None))
|
||||||
|
.and_then(|rs| rs.first())
|
||||||
|
{
|
||||||
let msg = deserialize_shared_message(tt.clone(), de)?;
|
let msg = deserialize_shared_message(tt.clone(), de)?;
|
||||||
|
|
||||||
Ok(rs.send_boxed(self, mid, msg.upcast_box(), false, rs.reserve(&tt).await)?)
|
Ok(rs.send_boxed(self, mid, msg.upcast_box(), false, rs.reserve(&tt).await)?)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NoReceivers)
|
Err(Error::NoReceivers)
|
||||||
@ -635,10 +754,7 @@ impl Bus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn stats(&self) -> impl Iterator<Item = Stats> + '_ {
|
pub fn stats(&self) -> impl Iterator<Item = Stats> + '_ {
|
||||||
self.inner
|
self.inner.receivers.iter().map(|x| x.stats())
|
||||||
.receivers
|
|
||||||
.iter()
|
|
||||||
.map(|x| x.stats())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -650,14 +766,16 @@ impl Bus {
|
|||||||
eid: Option<TypeTag>,
|
eid: Option<TypeTag>,
|
||||||
is_req: bool,
|
is_req: bool,
|
||||||
) -> impl Iterator<Item = &Receiver> + '_ {
|
) -> impl Iterator<Item = &Receiver> + '_ {
|
||||||
self.inner.lookup.get(&(tid.clone(), rid.clone(), eid.clone()))
|
self.inner
|
||||||
|
.lookup
|
||||||
|
.get(&(tid.clone(), rid.clone(), eid.clone()))
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.filter(move |r| r.accept(is_req, &tid, rid.as_ref(), eid.as_ref()))
|
.filter(move |r| r.accept(is_req, &tid, rid.as_ref(), eid.as_ref()))
|
||||||
.filter(move |r| match options {
|
.filter(move |r| match options {
|
||||||
SendOptions::Except(id) => id != r.id(),
|
SendOptions::Except(id) => id != r.id(),
|
||||||
SendOptions::Direct(id) => id == r.id(),
|
SendOptions::Direct(id) => id == r.id(),
|
||||||
_ => true
|
_ => true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,9 @@ use core::{
|
|||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::atomic::{AtomicBool, AtomicI64, Ordering},
|
sync::atomic::{AtomicBool, AtomicI64, Ordering},
|
||||||
};
|
};
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use futures::{pin_mut, Stream};
|
use futures::{pin_mut, Stream};
|
||||||
use futures::{Future, FutureExt, StreamExt};
|
use futures::{Future, FutureExt, StreamExt};
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
use std::{borrow::Cow, sync::Arc};
|
use std::{borrow::Cow, sync::Arc};
|
||||||
use tokio::sync::{oneshot, Notify};
|
use tokio::sync::{oneshot, Notify};
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ where
|
|||||||
if self.context.resend_unused_resp {
|
if self.context.resend_unused_resp {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
Ok(None) => (),
|
Ok(None) => (),
|
||||||
Err(err) => error!("Response Error: {}", err),
|
Err(err) => error!("Response Error: {}", err),
|
||||||
@ -350,8 +350,11 @@ where
|
|||||||
E: StdSyncSendError,
|
E: StdSyncSendError,
|
||||||
S: ReciveTypedReceiver<R, E> + Send + Sync + 'static,
|
S: ReciveTypedReceiver<R, E> + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
fn iter_types(&self) -> Box<dyn Iterator<Item = (TypeTag, Option<(TypeTag, TypeTag)>)> + '_> {
|
fn iter_types(&self) -> Box<dyn Iterator<Item = (TypeTag, Option<(TypeTag, TypeTag)>)> + '_> {
|
||||||
Box::new(std::iter::once((M::type_tag_(), Some((R::type_tag_(), E::type_tag_())))))
|
Box::new(std::iter::once((
|
||||||
|
M::type_tag_(),
|
||||||
|
Some((R::type_tag_(), E::type_tag_())),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept_req(&self, req: &TypeTag, resp: Option<&TypeTag>, err: Option<&TypeTag>) -> bool {
|
fn accept_req(&self, req: &TypeTag, resp: Option<&TypeTag>, err: Option<&TypeTag>) -> bool {
|
||||||
@ -411,7 +414,7 @@ where
|
|||||||
.map_err(|_| Error::MessageCastError)?;
|
.map_err(|_| Error::MessageCastError)?;
|
||||||
|
|
||||||
SendTypedReceiver::send(&self.inner, mid, *boxed, req, bus)
|
SendTypedReceiver::send(&self.inner, mid, *boxed, req, bus)
|
||||||
.map_err(|err| err.map_msg(|m|m.into_boxed()))
|
.map_err(|err| err.map_msg(|m| m.into_boxed()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stats(&self) -> Stats {
|
fn stats(&self) -> Stats {
|
||||||
@ -794,7 +797,13 @@ impl Receiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn accept(&self, is_req: bool, msg: &TypeTag, resp: Option<&TypeTag>, err: Option<&TypeTag>) -> bool {
|
pub fn accept(
|
||||||
|
&self,
|
||||||
|
is_req: bool,
|
||||||
|
msg: &TypeTag,
|
||||||
|
resp: Option<&TypeTag>,
|
||||||
|
err: Option<&TypeTag>,
|
||||||
|
) -> bool {
|
||||||
if is_req {
|
if is_req {
|
||||||
self.inner.accept_req(msg, resp, err)
|
self.inner.accept_req(msg, resp, err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,7 +52,7 @@ async fn test_backpressure() {
|
|||||||
|
|
||||||
assert!(b.try_send(MsgF32(32f32)).is_err());
|
assert!(b.try_send(MsgF32(32f32)).is_err());
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
b.close().await;
|
b.close().await;
|
||||||
poller.await;
|
poller.await;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ async fn test_batch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
println!("flush");
|
println!("flush");
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
let mut lock = batches.lock();
|
let mut lock = batches.lock();
|
||||||
lock.sort_by(|a, b| a[0].cmp(&b[0]));
|
lock.sort_by(|a, b| a[0].cmp(&b[0]));
|
||||||
|
@ -113,7 +113,7 @@ async fn test_sync() {
|
|||||||
|
|
||||||
println!("sent");
|
println!("sent");
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
|
|
||||||
println!("flushed");
|
println!("flushed");
|
||||||
|
|
||||||
|
@ -2,7 +2,12 @@ use std::pin::Pin;
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use messagebus::{Action, AsyncHandler, Bus, Event, Message, MessageBounds, ReciveUntypedReceiver, SendUntypedReceiver, TypeTag, TypeTagAccept, TypeTagged, derive::{Error as MbError, Message}, error::{self, GenericError}, receivers};
|
use messagebus::{
|
||||||
|
derive::{Error as MbError, Message},
|
||||||
|
error::{self, GenericError},
|
||||||
|
receivers, Action, AsyncHandler, Bus, Event, Message, MessageBounds, ReciveUntypedReceiver,
|
||||||
|
SendUntypedReceiver, TypeTag, TypeTagAccept, TypeTagged,
|
||||||
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
@ -60,32 +65,29 @@ impl TypeTagAccept for TestRelay {
|
|||||||
if msg.as_ref() == Msg::<i16>::type_tag_().as_ref() {
|
if msg.as_ref() == Msg::<i16>::type_tag_().as_ref() {
|
||||||
if let Some(resp) = resp {
|
if let Some(resp) = resp {
|
||||||
if resp.as_ref() == Msg::<u8>::type_tag_().as_ref() {
|
if resp.as_ref() == Msg::<u8>::type_tag_().as_ref() {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.as_ref() == Msg::<i32>::type_tag_().as_ref() {
|
if msg.as_ref() == Msg::<i32>::type_tag_().as_ref() {
|
||||||
if let Some(resp) = resp {
|
if let Some(resp) = resp {
|
||||||
if resp.as_ref() == Msg::<u64>::type_tag_().as_ref() {
|
if resp.as_ref() == Msg::<u64>::type_tag_().as_ref() {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept_msg(
|
fn accept_msg(&self, msg: &messagebus::TypeTag) -> bool {
|
||||||
&self,
|
|
||||||
msg: &messagebus::TypeTag,
|
|
||||||
) -> bool {
|
|
||||||
if msg.as_ref() == Msg::<i32>::type_tag_().as_ref() {
|
if msg.as_ref() == Msg::<i32>::type_tag_().as_ref() {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
@ -94,8 +96,14 @@ impl TypeTagAccept for TestRelay {
|
|||||||
fn iter_types(&self) -> Box<dyn Iterator<Item = (TypeTag, Option<(TypeTag, TypeTag)>)>> {
|
fn iter_types(&self) -> Box<dyn Iterator<Item = (TypeTag, Option<(TypeTag, TypeTag)>)>> {
|
||||||
Box::new(
|
Box::new(
|
||||||
std::iter::once((Msg::<i32>::type_tag_(), None))
|
std::iter::once((Msg::<i32>::type_tag_(), None))
|
||||||
.chain(std::iter::once((Msg::<i32>::type_tag_(), Some((Msg::<u64>::type_tag_(), GenericError::type_tag_())))))
|
.chain(std::iter::once((
|
||||||
.chain(std::iter::once((Msg::<i16>::type_tag_(), Some((Msg::<u8>::type_tag_(), GenericError::type_tag_())))))
|
Msg::<i32>::type_tag_(),
|
||||||
|
Some((Msg::<u64>::type_tag_(), GenericError::type_tag_())),
|
||||||
|
)))
|
||||||
|
.chain(std::iter::once((
|
||||||
|
Msg::<i16>::type_tag_(),
|
||||||
|
Some((Msg::<u8>::type_tag_(), GenericError::type_tag_())),
|
||||||
|
))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,7 +198,7 @@ async fn test_relay() {
|
|||||||
assert_eq!(res1.0, 9u8);
|
assert_eq!(res1.0, 9u8);
|
||||||
assert_eq!(res2.0, 22u64);
|
assert_eq!(res2.0, 22u64);
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
b.close().await;
|
b.close().await;
|
||||||
poller.await;
|
poller.await;
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ async fn test() {
|
|||||||
|
|
||||||
assert!((val - 1633.0f64).abs() < f64::EPSILON);
|
assert!((val - 1633.0f64).abs() < f64::EPSILON);
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
b.close().await;
|
b.close().await;
|
||||||
poller.await;
|
poller.await;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ async fn test() {
|
|||||||
assert_eq!(val.type_tag(), TypeTag::from("MsgResponse"));
|
assert_eq!(val.type_tag(), TypeTag::from("MsgResponse"));
|
||||||
assert_eq!(buff.as_slice(), br#"{"test1":24,"test2":"Hello, World!"}"#);
|
assert_eq!(buff.as_slice(), br#"{"test1":24,"test2":"Hello, World!"}"#);
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
b.close().await;
|
b.close().await;
|
||||||
poller.await;
|
poller.await;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ async fn test_shared() {
|
|||||||
b.send_one(Msg).await.unwrap();
|
b.send_one(Msg).await.unwrap();
|
||||||
b.send_one(SharedMsg(0.0f32)).await.unwrap();
|
b.send_one(SharedMsg(0.0f32)).await.unwrap();
|
||||||
|
|
||||||
b.flush().await;
|
b.flush_all().await;
|
||||||
b.close().await;
|
b.close().await;
|
||||||
poller.await;
|
poller.await;
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ async fn test_sync() {
|
|||||||
b.send(MsgU16(11u16)).await.unwrap();
|
b.send(MsgU16(11u16)).await.unwrap();
|
||||||
b.send(MsgU32(32u32)).await.unwrap();
|
b.send(MsgU32(32u32)).await.unwrap();
|
||||||
|
|
||||||
b.flush_and_sync().await;
|
b.flush_and_sync_all().await;
|
||||||
b.close().await;
|
b.close().await;
|
||||||
poller.await;
|
poller.await;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user