use serde::{Serialize, Deserialize};
use net2::TcpStreamExt;
use rmp_serde;
use rand::{self, Rand};
use std::net::{TcpListener, TcpStream, ToSocketAddrs, Shutdown, SocketAddr};
use std::sync::{RwLock, Arc, Mutex};
use std::collections::HashMap;
use std::ops::Deref;
use std::fmt::Debug;
use std::hash::Hash;
use std::{mem, fmt};
use std::time::Duration;
use std::thread::{self, JoinHandle};
use std::io::{self, BufWriter};
use super::stats::{Stats, StatReader, StatWriter};
use super::queue::Queue;
pub trait Message: Serialize + Deserialize + Send + Sync + Clone + 'static {}
impl<T> Message for T where T: Serialize + Deserialize + Send + Sync + Clone + 'static {}
pub trait NodeId: Serialize + Deserialize + Send + Sync + Debug + Clone + Eq + Hash + 'static {}
impl<T> NodeId for T where T: Serialize + Deserialize + Send + Sync + Debug + Clone + Eq + Hash + 'static {}
pub trait InitMessage: Serialize + Deserialize + Send + Sync + Clone + Debug + 'static {}
impl<T> InitMessage for T where T: Serialize + Deserialize + Send + Sync + Clone + Debug + 'static {}
#[derive(Debug)]
pub enum Error<N> where N: NodeId {
AlreadyClosed,
OpenError(io::Error),
ConnectionError(io::Error),
SendError,
ReadError,
NotConnected(N),
ConnectionAborted,
CloseError(io::Error)
}
#[derive(PartialEq, Debug)]
pub enum Event<M: Message, N: NodeId, I: InitMessage> {
Message(N, M),
ConnectionRequest(ConnectionRequest<M, N, I>),
Connected(N),
Disconnected(N),
Closing,
Closed
}
pub struct CloseGuard<M: Message, N: NodeId, I: InitMessage>(Node<M, N, I>);
impl<M: Message, N: NodeId, I: InitMessage> Drop for CloseGuard<M, N, I> {
fn drop(&mut self) {
self.close().expect("Failed to close node");
}
}
impl<M: Message, N: NodeId, I: InitMessage> Deref for CloseGuard<M, N, I> {
type Target = Node<M, N, I>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub struct NodeStats<N: NodeId> {
pub connections: HashMap<N, ConnectionStats>
}
pub struct NodeInner<M: Message, N: NodeId, I: InitMessage> {
node_id: N,
events: Queue<Event<M, N, I>>,
sockets: Mutex<Vec<(Arc<TcpListener>, JoinHandle<Result<(), Error<N>>>)>>,
connections: RwLock<HashMap<N, Connection<M, N, I>>>,
closed: RwLock<bool>,
connection_timeout: Mutex<Duration>,
stats_halflife_time: Mutex<Duration>,
init_message: Mutex<I>,
}
#[derive(Clone)]
pub struct Node<M: Message, N: NodeId, I: InitMessage>(Arc<NodeInner<M, N, I>>);
impl<M: Message, N: NodeId, I: InitMessage> Deref for Node<M, N, I> {
type Target = NodeInner<M, N, I>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<M: Message, N: NodeId, I: InitMessage> Node<M, N, I> {
pub fn new(node_id: N, init_message: I) -> CloseGuard<M, N, I> {
CloseGuard(Node(Arc::new(NodeInner{
node_id: node_id,
events: Queue::new(),
sockets: Mutex::new(Vec::new()),
connections: RwLock::new(HashMap::new()),
closed: RwLock::new(false),
connection_timeout: Mutex::new(Duration::from_secs(60)),
stats_halflife_time: Mutex::new(Duration::from_secs(60)),
init_message: Mutex::new(init_message),
})))
}
pub fn set_connection_timeout(&self, dur: Duration) {
*self.connection_timeout.lock().expect("Lock poisoned") = dur;
}
pub fn connection_timeout(&self) -> Duration {
*self.connection_timeout.lock().expect("Lock poisoned")
}
pub fn set_stats_halflife_time(&self, dur: Duration) {
*self.stats_halflife_time.lock().expect("Lock poisoned") = dur;
}
pub fn stats_halflife_time(&self) -> Duration {
*self.stats_halflife_time.lock().expect("Lock poisoned")
}
pub fn set_init_message(&self, init: I) {
*self.init_message.lock().expect("Lock poisoned") = init;
}
pub fn init_message(&self) -> I {
self.init_message.lock().expect("Lock poisoned").clone()
}
pub fn listen<A: ToSocketAddrs>(&self, addr: A) -> Result<SocketAddr, Error<N>> {
if *self.closed.read().expect("Lock poisoned") {
return Err(Error::AlreadyClosed);
}
let mut nodes = self.sockets.lock().expect("Lock poisoned");
let node: Arc<TcpListener> = Arc::new(try!(TcpListener::bind(addr).map_err(|err| Error::OpenError(err))));
let cloned_self = self.clone();
let cloned_node = node.clone();
let used_addr = node.local_addr().expect("Failed to get local address");
let join = thread::spawn(move || cloned_self.run_node(cloned_node));
nodes.push((node, join));
Ok(used_addr)
}
pub fn listen_defaults(&self) -> Result<(), Error<N>> {
try!(self.listen("0.0.0.0:0"));
try!(self.listen("[::0]:0"));
Ok(())
}
pub fn addresses(&self) -> Vec<SocketAddr> {
let mut addrs = Vec::new();
for &(ref sock, _) in &self.sockets.lock().expect("Lock poisoned") as &Vec<(Arc<TcpListener>, _)> {
addrs.push(sock.local_addr().expect("Failed to obtain address"));
}
addrs
}
pub fn receive(&self) -> Event<M, N, I> {
match self.events.get() {
Some(evt) => evt,
None => Event::Closed
}
}
#[cfg(feature = "nightly")]
pub fn receive_timeout(&self, timeout: Duration) -> Option<Event<M, N, I>> {
match self.events.get_timeout(timeout) {
Some(Some(evt)) => Some(evt),
Some(None) => Some(Event::Closed),
None => None
}
}
pub fn node_id(&self) -> N {
self.node_id.clone()
}
fn handle_message(&self, src: N, msg: M) {
self.events.put(Event::Message(src, msg));
}
fn add_connection(&self, con: Connection<M, N, I>) {
let id = con.node_id().clone();
self.connections.write().expect("Lock poisoned").insert(id.clone(), con);
self.events.put(Event::Connected(id));
}
fn del_connection(&self, id: &N) {
self.connections.write().expect("Lock poisoned").remove(id);
self.events.put(Event::Disconnected(id.clone()));
}
fn get_connection(&self, id: &N) -> Option<Connection<M, N, I>> {
self.connections.read().expect("Lock poisoned").get(id).map(|v| v.clone())
}
pub fn is_connected(&self, id: &N) -> bool {
self.connections.read().expect("Lock poisoned").contains_key(id)
}
fn get_connections(&self) -> Vec<Connection<M, N, I>> {
self.connections.read().expect("Lock poisoned").values().map(|c| c.clone()).collect()
}
pub fn stats(&self) -> NodeStats<N> {
let mut stats = NodeStats{connections: HashMap::new()};
for (id, con) in self.connections.read().expect("Lock poisoned").iter() {
stats.connections.insert(id.clone(), con.stats());
}
stats
}
fn run_node(&self, socket: Arc<TcpListener>) -> Result<(), Error<N>> {
loop {
let (sock, _) = try!(socket.accept().map_err(|e| Error::ConnectionError(e)));
let req = try!(ConnectionRequest::new(self.clone(), sock));
self.events.put(Event::ConnectionRequest(req));
}
}
pub fn send(&self, dst: &N, msg: &M) -> Result<(), Error<N>> {
if dst == &self.node_id {
self.handle_message(dst.clone(), msg.clone());
return Ok(());
}
match self.get_connection(dst) {
Some(con) => con.send(msg),
None => Err(Error::NotConnected(dst.clone()))
}
}
pub fn connect_request<A: ToSocketAddrs>(&self, addr: A) -> Result<ConnectionRequest<M, N, I>, Error<N>> {
if *self.closed.read().expect("Lock poisoned") {
return Err(Error::AlreadyClosed);
}
let sock = try!(TcpStream::connect(addr).map_err(|err| Error::ConnectionError(err)));
Ok(try!(ConnectionRequest::new(self.clone(), sock)))
}
pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> Result<N, Error<N>> {
let req = try!(self.connect_request(addr));
let id = req.node_id().clone();
req.accept();
Ok(id)
}
fn shutdown_socket(&self, socket: &TcpListener) -> Result<(), Error<N>> {
let socket = unsafe { mem::transmute::<&TcpListener, &TcpStream>(socket) };
socket.shutdown(Shutdown::Both).map_err(|e| Error::CloseError(e))
}
fn accept_connection(&self, con: Connection<M, N, I>) {
self.add_connection(con.clone());
thread::spawn(move || con.run());
}
fn close(&self) -> Result<(), Error<N>> {
self.events.put(Event::Closing);
*self.closed.write().expect("Lock poisoned") = true;
let mut sockets = self.sockets.lock().expect("Lock poisoned");
while let Some((s, j)) = sockets.pop() {
try!(self.shutdown_socket(&s));
j.join().expect("Failed to join").ok();
}
for c in self.get_connections() {
let _ = c.close();
}
self.events.put(Event::Closed);
self.events.close();
Ok(())
}
}
impl<M: Message, N: NodeId, I: InitMessage> Node<M, N, I> where N: Rand {
pub fn with_random_id(init: I) -> CloseGuard<M, N, I> {
Node::new(rand::random::<N>(), init)
}
}
impl<M: Message, N: NodeId> Node<M, N, ()> {
pub fn without_init(node_id: N) -> CloseGuard<M, N, ()> {
Node::new(node_id, ())
}
}
impl<M: Message, N: NodeId> Node<M, N, ()> where N: Rand {
pub fn create_default() -> CloseGuard<M, N, ()> {
Node::new(rand::random::<N>(), ())
}
}
pub struct ConnectionStats {
pub write_total: u64,
pub write_rate: f64,
pub write_idle: Duration,
pub read_total: u64,
pub read_rate: f64,
pub read_idle: Duration
}
pub struct ConnectionRequest<M: Message, N: NodeId, I: InitMessage> {
node: Node<M, N, I>,
socket: TcpStream,
init: I,
node_id: N,
}
impl<M: Message, N: NodeId, I: InitMessage> PartialEq for ConnectionRequest<M, N, I> {
fn eq(&self, other: &Self) -> bool {
self.node_id == other.node_id
&& self.socket.peer_addr().unwrap() == other.socket.peer_addr().unwrap()
&& self.socket.local_addr().unwrap() == other.socket.local_addr().unwrap()
}
}
impl<M: Message, N: NodeId, I: InitMessage> fmt::Debug for ConnectionRequest<M, N, I> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(fmt, "ConnectionRequest(from: {:?}, node_id: {:?}, init: {:?})", self.socket.peer_addr().unwrap(), self.node_id, self.init)
}
}
impl<M: Message, N: NodeId, I: InitMessage> ConnectionRequest<M, N, I> {
fn new(node: Node<M, N, I>, mut socket: TcpStream) -> Result<Self, Error<N>> {
try!(socket.set_nodelay(true).map_err(|err| Error::ConnectionError(err)));
try!(socket.set_read_timeout(Some(node.connection_timeout())).map_err(|err| Error::ConnectionError(err)));
{
let mut writer = rmp_serde::Serializer::new(&mut socket);
try!((node.init_message(), node.node_id()).serialize(&mut writer).map_err(|_| Error::SendError));
}
let (init, node_id) = {
let mut reader = rmp_serde::Deserializer::new(&socket);
try!(Deserialize::deserialize(&mut reader).map_err(|_| Error::ReadError))
};
Ok(ConnectionRequest{node: node, socket: socket, init: init, node_id: node_id})
}
pub fn init_message(&self) -> &I {
&self.init
}
pub fn node_id(&self) -> &N {
&self.node_id
}
pub fn accept(self) {
let con = Connection::new(self.node.clone(), self.socket, self.node_id);
self.node.accept_connection(con);
}
pub fn reject(self) {
drop(self.socket);
}
}
pub struct ConnectionInner<M: Message, N: NodeId, I: InitMessage> {
node: Node<M, N, I>,
socket: Mutex<TcpStream>,
writer: Mutex<StatWriter<TcpStream>>,
writer_stats: Arc<RwLock<Stats>>,
reader: Mutex<rmp_serde::Deserializer<StatReader<TcpStream>>>,
reader_stats: Arc<RwLock<Stats>>,
node_id: N
}
#[derive(Clone)]
pub struct Connection<M: Message, N: NodeId, I: InitMessage>(Arc<ConnectionInner<M, N, I>>);
impl<M: Message, N: NodeId, I: InitMessage> Deref for Connection<M, N, I> {
type Target = ConnectionInner<M, N, I>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<M: Message, N: NodeId, I: InitMessage> Connection<M, N, I> {
fn new(node: Node<M, N, I>, socket: TcpStream, node_id: N) -> Self {
let writer = StatWriter::new(socket.try_clone().expect("Failed to clone socket"), node.stats_halflife_time());
let writer_stats = writer.stats();
let input = StatReader::new(socket.try_clone().expect("Failed to clone socket"), node.stats_halflife_time());
let reader_stats = input.stats();
let reader = rmp_serde::Deserializer::new(input);
Connection(Arc::new(ConnectionInner{
node: node,
writer: Mutex::new(writer),
writer_stats: writer_stats,
reader: Mutex::new(reader),
reader_stats: reader_stats,
socket: Mutex::new(socket),
node_id: node_id
}))
}
fn node_id(&self) -> &N {
&self.node_id
}
fn stats(&self) -> ConnectionStats {
let reader_stats = self.reader_stats.read().expect("Lock poisoned");
let writer_stats = self.writer_stats.read().expect("Lock poisoned");
ConnectionStats{
write_total: writer_stats.total(),
write_rate: writer_stats.rate(),
write_idle: writer_stats.idle_time(),
read_total: reader_stats.total(),
read_rate: reader_stats.rate(),
read_idle: reader_stats.idle_time()
}
}
fn send(&self, msg: &M) -> Result<(), Error<N>> {
let mut lock = self.writer.lock().expect("Lock poisoned");
let mut bufwriter = BufWriter::new(&mut lock as &mut StatWriter<TcpStream>);
let mut writer = rmp_serde::Serializer::new(&mut bufwriter);
msg.serialize(&mut writer).map_err(|_| Error::SendError)
}
fn run(&self) -> Result<(), Error<N>> {
let res = self.run_inner();
self.node.del_connection(&self.node_id);
res
}
fn run_inner(&self) -> Result<(), Error<N>> {
let mut reader = self.reader.lock().expect("Lock poisoned");
loop {
let msg = try!(M::deserialize(&mut reader as &mut rmp_serde::Deserializer<StatReader<TcpStream>>).map_err(|_| Error::ReadError));
self.node.handle_message(self.node_id.clone(), msg);
}
}
fn close(&self) -> Result<(), Error<N>> {
Ok(try!(self.socket.lock().expect("Lock poisoned").shutdown(Shutdown::Both).map_err(|err| Error::CloseError(err))))
}
}