2020-01-13 16:53:28 +00:00
|
|
|
use crate::{
|
2020-01-22 16:44:32 +00:00
|
|
|
internal::Channel,
|
2020-01-13 16:53:28 +00:00
|
|
|
message::{self, Message},
|
2020-01-22 16:44:32 +00:00
|
|
|
mio_worker::{CtrlMsg, MioWorker, TokenObjects},
|
2020-01-13 16:53:28 +00:00
|
|
|
tcp_channel::TcpChannel,
|
|
|
|
};
|
2019-12-20 13:56:01 +00:00
|
|
|
use enumset::*;
|
|
|
|
use mio::{
|
|
|
|
self,
|
|
|
|
net::{TcpListener, TcpStream},
|
2020-01-13 16:53:28 +00:00
|
|
|
PollOpt, Ready,
|
2019-12-20 13:56:01 +00:00
|
|
|
};
|
2020-01-22 16:44:32 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2020-01-13 16:53:28 +00:00
|
|
|
use std::{marker::PhantomData, sync::Arc};
|
2020-01-22 16:44:32 +00:00
|
|
|
use tlid;
|
2020-01-13 16:53:28 +00:00
|
|
|
use tracing::*;
|
|
|
|
use uuid::Uuid;
|
|
|
|
use uvth::ThreadPool;
|
2019-12-20 13:56:01 +00:00
|
|
|
|
2020-01-13 16:53:28 +00:00
|
|
|
#[derive(Clone, Debug)]
|
2019-12-20 13:56:01 +00:00
|
|
|
pub enum Address {
|
|
|
|
Tcp(std::net::SocketAddr),
|
|
|
|
Udp(std::net::SocketAddr),
|
|
|
|
}
|
|
|
|
|
2020-01-22 16:44:32 +00:00
|
|
|
#[derive(Serialize, Deserialize, EnumSetType, Debug)]
|
|
|
|
#[enumset(serialize_repr = "u8")]
|
2019-12-20 13:56:01 +00:00
|
|
|
pub enum Promise {
|
|
|
|
InOrder,
|
|
|
|
NoCorrupt,
|
|
|
|
GuaranteedDelivery,
|
|
|
|
Encrypted,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Participant {
|
|
|
|
addr: Address,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Connection {}
|
|
|
|
|
|
|
|
pub struct Stream {}
|
|
|
|
|
|
|
|
pub trait Events {
|
2020-01-13 16:53:28 +00:00
|
|
|
fn on_remote_connection_open(net: &Network<Self>, con: &Connection)
|
2019-12-20 13:56:01 +00:00
|
|
|
where
|
|
|
|
Self: std::marker::Sized;
|
2020-01-13 16:53:28 +00:00
|
|
|
fn on_remote_connection_close(net: &Network<Self>, con: &Connection)
|
2019-12-20 13:56:01 +00:00
|
|
|
where
|
|
|
|
Self: std::marker::Sized;
|
2020-01-13 16:53:28 +00:00
|
|
|
fn on_remote_stream_open(net: &Network<Self>, st: &Stream)
|
2019-12-20 13:56:01 +00:00
|
|
|
where
|
|
|
|
Self: std::marker::Sized;
|
2020-01-13 16:53:28 +00:00
|
|
|
fn on_remote_stream_close(net: &Network<Self>, st: &Stream)
|
2019-12-20 13:56:01 +00:00
|
|
|
where
|
|
|
|
Self: std::marker::Sized;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Network<E: Events> {
|
2020-01-22 16:44:32 +00:00
|
|
|
token_pool: tlid::Pool<tlid::Wrapping<usize>>,
|
2020-01-13 16:53:28 +00:00
|
|
|
mio_workers: Arc<Vec<MioWorker>>,
|
|
|
|
thread_pool: Arc<ThreadPool>,
|
|
|
|
participant_id: Uuid,
|
2019-12-20 13:56:01 +00:00
|
|
|
_pe: PhantomData<E>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<E: Events> Network<E> {
|
2020-01-13 16:53:28 +00:00
|
|
|
pub fn new(participant_id: Uuid, thread_pool: Arc<ThreadPool>) -> Self {
|
2020-01-22 16:44:32 +00:00
|
|
|
let mut token_pool = tlid::Pool::new_full();
|
2020-01-13 16:53:28 +00:00
|
|
|
let mio_workers = Arc::new(vec![MioWorker::new(
|
|
|
|
(participant_id.as_u128().rem_euclid(1024)) as u64,
|
2020-01-22 16:44:32 +00:00
|
|
|
participant_id,
|
2020-01-13 16:53:28 +00:00
|
|
|
thread_pool.clone(),
|
2020-01-22 16:44:32 +00:00
|
|
|
token_pool.subpool(1000000).unwrap(),
|
2020-01-13 16:53:28 +00:00
|
|
|
)]);
|
2019-12-20 13:56:01 +00:00
|
|
|
Self {
|
2020-01-22 16:44:32 +00:00
|
|
|
token_pool,
|
2020-01-13 16:53:28 +00:00
|
|
|
mio_workers,
|
2019-12-20 13:56:01 +00:00
|
|
|
thread_pool,
|
2020-01-13 16:53:28 +00:00
|
|
|
participant_id,
|
2019-12-20 13:56:01 +00:00
|
|
|
_pe: PhantomData::<E> {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-13 16:53:28 +00:00
|
|
|
fn get_lowest_worker<'a: 'b, 'b>(list: &'a Arc<Vec<MioWorker>>) -> &'a MioWorker { &list[0] }
|
|
|
|
|
|
|
|
pub fn send<'a, M: Message<'a>>(&self, msg: M, stream: &Stream) {
|
|
|
|
let messagebuffer = message::serialize(&msg);
|
|
|
|
}
|
2019-12-20 13:56:01 +00:00
|
|
|
|
|
|
|
pub fn listen(&self, addr: &Address) {
|
2020-01-22 16:44:32 +00:00
|
|
|
let worker = Self::get_lowest_worker(&self.mio_workers);
|
|
|
|
let pipe = worker.get_tx();
|
2020-01-13 16:53:28 +00:00
|
|
|
let address = addr.clone();
|
|
|
|
self.thread_pool.execute(move || {
|
2020-01-22 16:44:32 +00:00
|
|
|
let span = span!(Level::INFO, "listen", ?address);
|
2020-01-13 16:53:28 +00:00
|
|
|
let _enter = span.enter();
|
|
|
|
match address {
|
|
|
|
Address::Tcp(a) => {
|
|
|
|
info!("listening");
|
|
|
|
let tcp_listener = TcpListener::bind(&a).unwrap();
|
2020-01-22 16:44:32 +00:00
|
|
|
pipe.send(CtrlMsg::Register(
|
2020-01-13 16:53:28 +00:00
|
|
|
TokenObjects::TcpListener(tcp_listener),
|
|
|
|
Ready::readable(),
|
|
|
|
PollOpt::edge(),
|
2020-01-22 16:44:32 +00:00
|
|
|
))
|
|
|
|
.unwrap();
|
2020-01-13 16:53:28 +00:00
|
|
|
},
|
|
|
|
Address::Udp(_) => unimplemented!("lazy me"),
|
|
|
|
}
|
2019-12-20 13:56:01 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-01-13 16:53:28 +00:00
|
|
|
pub fn connect(&self, addr: &Address) -> Participant {
|
2020-01-22 16:44:32 +00:00
|
|
|
let worker = Self::get_lowest_worker(&self.mio_workers);
|
|
|
|
let pipe = worker.get_tx();
|
2020-01-13 16:53:28 +00:00
|
|
|
let address = addr.clone();
|
2020-01-22 16:44:32 +00:00
|
|
|
let pid = self.participant_id;
|
2020-01-13 16:53:28 +00:00
|
|
|
self.thread_pool.execute(move || {
|
|
|
|
let mut span = span!(Level::INFO, "connect", ?address);
|
|
|
|
let _enter = span.enter();
|
|
|
|
match address {
|
|
|
|
Address::Tcp(a) => {
|
|
|
|
info!("connecting");
|
|
|
|
let tcp_stream = match TcpStream::connect(&a) {
|
|
|
|
Err(err) => {
|
|
|
|
error!("could not open connection: {}", err);
|
|
|
|
return;
|
2019-12-20 13:56:01 +00:00
|
|
|
},
|
2020-01-13 16:53:28 +00:00
|
|
|
Ok(s) => s,
|
|
|
|
};
|
2020-01-22 16:44:32 +00:00
|
|
|
let mut channel = TcpChannel::new(tcp_stream);
|
|
|
|
channel.handshake();
|
|
|
|
channel.participant_id(pid);
|
|
|
|
pipe.send(CtrlMsg::Register(
|
|
|
|
TokenObjects::TcpChannel(channel),
|
|
|
|
Ready::readable() | Ready::writable(),
|
2020-01-13 16:53:28 +00:00
|
|
|
PollOpt::edge(),
|
2020-01-22 16:44:32 +00:00
|
|
|
))
|
|
|
|
.unwrap();
|
2019-12-20 13:56:01 +00:00
|
|
|
},
|
2020-01-13 16:53:28 +00:00
|
|
|
Address::Udp(_) => unimplemented!("lazy me"),
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Participant { addr: addr.clone() }
|
2019-12-20 13:56:01 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 16:44:32 +00:00
|
|
|
pub fn open(&self, part: Participant, prio: u8, promises: EnumSet<Promise>) -> Stream {
|
|
|
|
for worker in self.mio_workers.iter() {
|
|
|
|
worker.get_tx().send(CtrlMsg::OpenStream {
|
|
|
|
pid: uuid::Uuid::new_v4(),
|
|
|
|
prio,
|
|
|
|
promises,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
Stream {}
|
|
|
|
}
|
2020-01-13 16:53:28 +00:00
|
|
|
|
|
|
|
pub fn close(&self, stream: Stream) {}
|
2019-12-20 13:56:01 +00:00
|
|
|
}
|