diff --git a/ipc/nano/src/lib.rs b/ipc/nano/src/lib.rs index 9d74325fa..18a5b0ffe 100644 --- a/ipc/nano/src/lib.rs +++ b/ipc/nano/src/lib.rs @@ -28,6 +28,7 @@ use std::ops::Deref; const POLL_TIMEOUT: isize = 100; +/// Generic worker to handle service (binded) sockets pub struct Worker where S: IpcInterface { service: Arc, sockets: Vec<(Socket, Endpoint)>, @@ -35,6 +36,8 @@ pub struct Worker where S: IpcInterface { buf: Vec, } +/// struct for guarding `_endpoint` (so that it wont drop) +/// derefs to client `S` pub struct GuardedSocket where S: WithSocket { client: Arc, _endpoint: Endpoint, @@ -48,6 +51,9 @@ impl Deref for GuardedSocket where S: WithSocket { } } +/// Spawns client <`S`> over specified address +/// creates socket and connects endpoint to it +/// for duplex (paired) connections with the service pub fn init_client(socket_addr: &str) -> Result, SocketError> where S: WithSocket { let mut socket = try!(Socket::new(Protocol::Pair).map_err(|e| { warn!(target: "ipc", "Failed to create ipc socket: {:?}", e); @@ -65,12 +71,15 @@ pub fn init_client(socket_addr: &str) -> Result, SocketError }) } +/// Error occured while establising socket or endpoint #[derive(Debug)] pub enum SocketError { + /// Error establising duplex (paired) socket and/or endpoint DuplexLink } impl Worker where S: IpcInterface { + /// New worker over specified `service` pub fn new(service: Arc) -> Worker { Worker:: { service: service.clone(), @@ -80,6 +89,7 @@ impl Worker where S: IpcInterface { } } + /// Polls all sockets, reads and dispatches method invocations pub fn poll(&mut self) { let mut request = PollRequest::new(&mut self.polls[..]); let _result_guard = Socket::poll(&mut request, POLL_TIMEOUT); @@ -119,12 +129,15 @@ impl Worker where S: IpcInterface { } } + /// Stores nanomsg poll request for reuse fn rebuild_poll_request(&mut self) { self.polls = self.sockets.iter() .map(|&(ref socket, _)| socket.new_pollfd(PollInOut::In)) .collect::>(); } + /// Add exclusive socket for paired client + /// Only one connection over this address is allowed pub fn add_duplex(&mut self, addr: &str) -> Result<(), SocketError> { let mut socket = try!(Socket::new(Protocol::Pair).map_err(|e| { warn!(target: "ipc", "Failed to create ipc socket: {:?}", e); diff --git a/ipc/rpc/src/interface.rs b/ipc/rpc/src/interface.rs index e1a0be2d5..820994a2b 100644 --- a/ipc/rpc/src/interface.rs +++ b/ipc/rpc/src/interface.rs @@ -20,26 +20,35 @@ use std::io::{Read, Write}; use std::marker::Sync; use semver::Version; +/// Handshake for client and server to negotiate api/protocol version pub struct Handshake { pub protocol_version: Version, pub api_version: Version, } +/// Allows to configure custom version and custom handshake response for +/// ipc host pub trait IpcConfig { + /// Current service api version + /// Should be increased if any of the methods changes signature fn api_version() -> Version { Version::parse("1.0.0").unwrap() } + /// Current ipc protocol version + /// Should be increased only if signature of system methods changes fn protocol_version() -> Version { Version::parse("1.0.0").unwrap() } + /// Default handshake requires exact versions match fn handshake(handshake: &Handshake) -> bool { handshake.protocol_version == Self::protocol_version() && handshake.api_version == Self::api_version() } } +/// Error in dispatching or invoking methods via IPC #[derive(Debug)] pub enum Error { UnkownSystemCall, @@ -48,6 +57,8 @@ pub enum Error { HandshakeFailed, } +/// Allows implementor to be attached to generic worker and dispatch rpc requests +/// over IPC pub trait IpcInterface: IpcConfig { /// reads the message from io, dispatches the call and returns serialized result fn dispatch(&self, r: &mut R) -> Vec where R: Read; @@ -79,11 +90,11 @@ pub fn invoke(method_num: u16, params: &Option>, w: &mut W) where W: } } -/// IpcSocket +/// IpcSocket, read/write generalization pub trait IpcSocket: Read + Write + Sync { } - +/// Basically something that needs only socket to be spawned pub trait WithSocket { fn init(socket: S) -> Self; }