Просмотр исходного кода

first draft of net module documentation is complete

rachel-rose 5 лет назад
Родитель
Сommit
7699206e86

+ 16 - 5
src/net/acceptor.rs

@@ -7,21 +7,25 @@ use crate::net::error::{NetError, NetResult};
 use crate::net::{Channel, ChannelPtr};
 use crate::net::{Channel, ChannelPtr};
 use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription};
 use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription};
 
 
+/// Atomic pointer to Acceptor class.
 pub type AcceptorPtr = Arc<Acceptor>;
 pub type AcceptorPtr = Arc<Acceptor>;
 
 
+/// Handles the acceptance of inbound socket connections. Used to start listening on a local
+/// socket address, to accept incoming connections and to handle network errors.
 pub struct Acceptor {
 pub struct Acceptor {
     channel_subscriber: SubscriberPtr<NetResult<ChannelPtr>>,
     channel_subscriber: SubscriberPtr<NetResult<ChannelPtr>>,
     task: StoppableTaskPtr,
     task: StoppableTaskPtr,
 }
 }
 
 
 impl Acceptor {
 impl Acceptor {
+    /// Create new Acceptor object.
     pub fn new() -> Arc<Self> {
     pub fn new() -> Arc<Self> {
         Arc::new(Self {
         Arc::new(Self {
             channel_subscriber: Subscriber::new(),
             channel_subscriber: Subscriber::new(),
             task: StoppableTask::new(),
             task: StoppableTask::new(),
         })
         })
     }
     }
-
+    /// Start accepting inbound socket connections.
     pub fn start(
     pub fn start(
         self: Arc<Self>,
         self: Arc<Self>,
         accept_addr: SocketAddr,
         accept_addr: SocketAddr,
@@ -34,16 +38,19 @@ impl Acceptor {
 
 
         Ok(())
         Ok(())
     }
     }
-
+    
+    /// Stop accepting inbound socket connections.
     pub async fn stop(&self) {
     pub async fn stop(&self) {
         // Send stop signal
         // Send stop signal
         self.task.stop().await;
         self.task.stop().await;
     }
     }
-
+    
+    /// Start receiving network messages.
     pub async fn subscribe(self: Arc<Self>) -> Subscription<NetResult<ChannelPtr>> {
     pub async fn subscribe(self: Arc<Self>) -> Subscription<NetResult<ChannelPtr>> {
         self.channel_subscriber.clone().subscribe().await
         self.channel_subscriber.clone().subscribe().await
     }
     }
-
+    
+    /// Start listening on a local socket address.
     fn setup(accept_addr: SocketAddr) -> NetResult<Async<TcpListener>> {
     fn setup(accept_addr: SocketAddr) -> NetResult<Async<TcpListener>> {
         let listener = match Async::<TcpListener>::bind(accept_addr) {
         let listener = match Async::<TcpListener>::bind(accept_addr) {
             Ok(listener) => listener,
             Ok(listener) => listener,
@@ -64,6 +71,7 @@ impl Acceptor {
         Ok(listener)
         Ok(listener)
     }
     }
 
 
+    /// Run the accept loop in a new thread and error if a connection problem occurs.
     fn accept(self: Arc<Self>, listener: Async<TcpListener>, executor: Arc<Executor<'_>>) {
     fn accept(self: Arc<Self>, listener: Async<TcpListener>, executor: Arc<Executor<'_>>) {
         self.task.clone().start(
         self.task.clone().start(
             self.clone().run_accept_loop(listener),
             self.clone().run_accept_loop(listener),
@@ -73,6 +81,7 @@ impl Acceptor {
         );
         );
     }
     }
 
 
+    /// Run the accept loop.
     async fn run_accept_loop(self: Arc<Self>, listener: Async<TcpListener>) -> NetResult<()> {
     async fn run_accept_loop(self: Arc<Self>, listener: Async<TcpListener>) -> NetResult<()> {
         loop {
         loop {
             let channel = self.tick_accept(&listener).await?;
             let channel = self.tick_accept(&listener).await?;
@@ -80,6 +89,7 @@ impl Acceptor {
         }
         }
     }
     }
 
 
+    /// Handles network errors. Panics if error passes silently, otherwise broadcasts the error.
     async fn handle_stop(self: Arc<Self>, result: NetResult<()>) {
     async fn handle_stop(self: Arc<Self>, result: NetResult<()>) {
         match result {
         match result {
             Ok(()) => panic!("Acceptor task should never complete without error status"),
             Ok(()) => panic!("Acceptor task should never complete without error status"),
@@ -90,7 +100,8 @@ impl Acceptor {
             }
             }
         }
         }
     }
     }
-
+    
+    /// Single attempt to accept an incoming connection. Stops after one attempt.
     async fn tick_accept(&self, listener: &Async<TcpListener>) -> NetResult<ChannelPtr> {
     async fn tick_accept(&self, listener: &Async<TcpListener>) -> NetResult<ChannelPtr> {
         let (stream, peer_addr) = match listener.accept().await {
         let (stream, peer_addr) = match listener.accept().await {
             Ok((s, a)) => (s, a),
             Ok((s, a)) => (s, a),

+ 21 - 7
src/net/channel.rs

@@ -15,8 +15,10 @@ use crate::net::message_subscriber::{MessageSubscription, MessageSubsystem};
 use crate::net::messages;
 use crate::net::messages;
 use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription};
 use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription};
 
 
+/// Atomic pointer to async channel.
 pub type ChannelPtr = Arc<Channel>;
 pub type ChannelPtr = Arc<Channel>;
 
 
+/// Async TCP channel that handles the sending of messages across the network.
 pub struct Channel {
 pub struct Channel {
     reader: Mutex<ReadHalf<Async<TcpStream>>>,
     reader: Mutex<ReadHalf<Async<TcpStream>>>,
     writer: Mutex<WriteHalf<Async<TcpStream>>>,
     writer: Mutex<WriteHalf<Async<TcpStream>>>,
@@ -28,6 +30,7 @@ pub struct Channel {
 }
 }
 
 
 impl Channel {
 impl Channel {
+    /// Create a new channel.
     pub async fn new(
     pub async fn new(
         stream: Async<TcpStream>,
         stream: Async<TcpStream>,
         address: SocketAddr,
         address: SocketAddr,
@@ -49,7 +52,8 @@ impl Channel {
             stopped: AtomicBool::new(false),
             stopped: AtomicBool::new(false),
         })
         })
     }
     }
-
+    
+    /// Start the channel.
     pub fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) {
     pub fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) {
         debug!(target: "net", "Channel::start() [START, address={}]", self.address());
         debug!(target: "net", "Channel::start() [START, address={}]", self.address());
         let self2 = self.clone();
         let self2 = self.clone();
@@ -62,7 +66,8 @@ impl Channel {
         );
         );
         debug!(target: "net", "Channel::start() [END, address={}]", self.address());
         debug!(target: "net", "Channel::start() [END, address={}]", self.address());
     }
     }
-
+    
+    /// Stop the channel.
     pub async fn stop(&self) {
     pub async fn stop(&self) {
         debug!(target: "net", "Channel::stop() [START, address={}]", self.address());
         debug!(target: "net", "Channel::stop() [START, address={}]", self.address());
         assert_eq!(self.stopped.load(Ordering::Relaxed), false);
         assert_eq!(self.stopped.load(Ordering::Relaxed), false);
@@ -73,6 +78,7 @@ impl Channel {
         debug!(target: "net", "Channel::stop() [END, address={}]", self.address());
         debug!(target: "net", "Channel::stop() [END, address={}]", self.address());
     }
     }
 
 
+    /// Stop the channel and create a new sub.
     pub async fn subscribe_stop(&self) -> Subscription<NetError> {
     pub async fn subscribe_stop(&self) -> Subscription<NetError> {
         debug!(target: "net",
         debug!(target: "net",
             "Channel::subscribe_stop() [START, address={}]",
             "Channel::subscribe_stop() [START, address={}]",
@@ -87,7 +93,8 @@ impl Channel {
         );
         );
         sub
         sub
     }
     }
-
+    
+    /// Send a message across a channel. 
     pub async fn send<M: messages::Message>(&self, message: M) -> NetResult<()> {
     pub async fn send<M: messages::Message>(&self, message: M) -> NetResult<()> {
         debug!(target: "net",
         debug!(target: "net",
             "Channel::send() [START, command={:?}, address={}]",
             "Channel::send() [START, command={:?}, address={}]",
@@ -114,7 +121,8 @@ impl Channel {
         );
         );
         result
         result
     }
     }
-
+    
+    /// Implements send message functionality.
     async fn send_message<M: messages::Message>(&self, message: M) -> error::Result<()> {
     async fn send_message<M: messages::Message>(&self, message: M) -> error::Result<()> {
         let mut payload = Vec::new();
         let mut payload = Vec::new();
         message.encode(&mut payload)?;
         message.encode(&mut payload)?;
@@ -127,6 +135,7 @@ impl Channel {
         messages::send_packet(stream, packet).await
         messages::send_packet(stream, packet).await
     }
     }
 
 
+    /// Subscribe to a message type.
     pub async fn subscribe_msg<M: messages::Message>(&self) -> NetResult<MessageSubscription<M>> {
     pub async fn subscribe_msg<M: messages::Message>(&self) -> NetResult<MessageSubscription<M>> {
         debug!(target: "net",
         debug!(target: "net",
             "Channel::subscribe_msg() [START, command={:?}, address={}]",
             "Channel::subscribe_msg() [START, command={:?}, address={}]",
@@ -141,11 +150,13 @@ impl Channel {
         );
         );
         sub
         sub
     }
     }
-
+    
+    /// Return the local socket address.
     pub fn address(&self) -> SocketAddr {
     pub fn address(&self) -> SocketAddr {
         self.address
         self.address
     }
     }
-
+    
+    /// End of file error. Triggered when unexpected end of file occurs.
     fn is_eof_error(err: &error::Error) -> bool {
     fn is_eof_error(err: &error::Error) -> bool {
         match err {
         match err {
             error::Error::Io(io_err) => io_err.kind() == std::io::ErrorKind::UnexpectedEof,
             error::Error::Io(io_err) => io_err.kind() == std::io::ErrorKind::UnexpectedEof,
@@ -153,6 +164,7 @@ impl Channel {
         }
         }
     }
     }
 
 
+    /// Perform network handshake for message subsystem dispatchers.
     async fn setup_dispatchers(message_subsystem: &MessageSubsystem) {
     async fn setup_dispatchers(message_subsystem: &MessageSubsystem) {
         message_subsystem
         message_subsystem
             .add_dispatch::<messages::VersionMessage>()
             .add_dispatch::<messages::VersionMessage>()
@@ -173,7 +185,8 @@ impl Channel {
             .add_dispatch::<messages::AddrsMessage>()
             .add_dispatch::<messages::AddrsMessage>()
             .await;
             .await;
     }
     }
-
+    
+    /// Run the receive loop. Start receiving messages or handle network failure.
     async fn main_receive_loop(self: Arc<Self>) -> NetResult<()> {
     async fn main_receive_loop(self: Arc<Self>) -> NetResult<()> {
         debug!(target: "net",
         debug!(target: "net",
             "Channel::receive_loop() [START, address={}]",
             "Channel::receive_loop() [START, address={}]",
@@ -207,6 +220,7 @@ impl Channel {
         }
         }
     }
     }
 
 
+    /// Handle network errors. Panic if error passes silently, otherwise broadcast the error.
     async fn handle_stop(self: Arc<Self>, result: NetResult<()>) {
     async fn handle_stop(self: Arc<Self>, result: NetResult<()>) {
         debug!(target: "net", "Channel::handle_stop() [START, address={}]", self.address());
         debug!(target: "net", "Channel::handle_stop() [START, address={}]", self.address());
         match result {
         match result {

+ 4 - 1
src/net/connector.rs

@@ -6,15 +6,18 @@ use crate::net::error::{NetError, NetResult};
 use crate::net::utility::sleep;
 use crate::net::utility::sleep;
 use crate::net::{Channel, ChannelPtr, SettingsPtr};
 use crate::net::{Channel, ChannelPtr, SettingsPtr};
 
 
+/// Handles the creation of outbound connections.
 pub struct Connector {
 pub struct Connector {
     settings: SettingsPtr,
     settings: SettingsPtr,
 }
 }
 
 
 impl Connector {
 impl Connector {
+    /// Create a new connector with default network settings.
     pub fn new(settings: SettingsPtr) -> Self {
     pub fn new(settings: SettingsPtr) -> Self {
         Self { settings }
         Self { settings }
     }
     }
-
+    
+    /// Establish an outbound connection.
     pub async fn connect(&self, hostaddr: SocketAddr) -> NetResult<ChannelPtr> {
     pub async fn connect(&self, hostaddr: SocketAddr) -> NetResult<ChannelPtr> {
         futures::select! {
         futures::select! {
             stream_result = Async::<TcpStream>::connect(hostaddr).fuse() => {
             stream_result = Async::<TcpStream>::connect(hostaddr).fuse() => {

+ 2 - 0
src/net/error.rs

@@ -1,7 +1,9 @@
 use std::fmt;
 use std::fmt;
 
 
+/// Returns the relevant network error if a program fails.
 pub type NetResult<T> = std::result::Result<T, NetError>;
 pub type NetResult<T> = std::result::Result<T, NetError>;
 
 
+/// Defines a set of common network errors. Used for error handling.
 #[derive(Debug, Copy, Clone)]
 #[derive(Debug, Copy, Clone)]
 pub enum NetError {
 pub enum NetError {
     OperationFailed,
     OperationFailed,

+ 10 - 2
src/net/hosts.rs

@@ -4,30 +4,36 @@ use std::net::SocketAddr;
 use std::sync::Arc;
 use std::sync::Arc;
 use std::collections::HashSet;
 use std::collections::HashSet;
 
 
+/// Pointer to hosts class.
 pub type HostsPtr = Arc<Hosts>;
 pub type HostsPtr = Arc<Hosts>;
 
 
+/// Manages a store of network addresses.
 pub struct Hosts {
 pub struct Hosts {
     addrs: Mutex<Vec<SocketAddr>>,
     addrs: Mutex<Vec<SocketAddr>>,
 }
 }
 
 
 impl Hosts {
 impl Hosts {
+    /// Create a new host list.
     pub fn new() -> Arc<Self> {
     pub fn new() -> Arc<Self> {
         Arc::new(Self {
         Arc::new(Self {
             addrs: Mutex::new(Vec::new()),
             addrs: Mutex::new(Vec::new()),
         })
         })
     }
     }
-
+    
+    /// Checks if a host address is in the host list.
     async fn contains(&self, addrs: &Vec<SocketAddr>) -> bool {
     async fn contains(&self, addrs: &Vec<SocketAddr>) -> bool {
         let a_set: HashSet<_> = addrs.iter().copied().collect();
         let a_set: HashSet<_> = addrs.iter().copied().collect();
         self.addrs.lock().await.iter().any(|item| a_set.contains(item))
         self.addrs.lock().await.iter().any(|item| a_set.contains(item))
     }
     }
 
 
+    /// Add a new host to the host list.
     pub async fn store(&self, addrs: Vec<SocketAddr>) {
     pub async fn store(&self, addrs: Vec<SocketAddr>) {
         if !self.contains(&addrs).await {
         if !self.contains(&addrs).await {
             self.addrs.lock().await.extend(addrs)
             self.addrs.lock().await.extend(addrs)
         }
         }
     }
     }
-
+    
+    /// Return a single host address.
     pub async fn load_single(&self) -> Option<SocketAddr> {
     pub async fn load_single(&self) -> Option<SocketAddr> {
         self.addrs
         self.addrs
             .lock()
             .lock()
@@ -36,10 +42,12 @@ impl Hosts {
             .cloned()
             .cloned()
     }
     }
 
 
+    /// Return the list of hosts.
     pub async fn load_all(&self) -> Vec<SocketAddr> {
     pub async fn load_all(&self) -> Vec<SocketAddr> {
         self.addrs.lock().await.clone()
         self.addrs.lock().await.clone()
     }
     }
 
 
+    /// Check if the host list is empty.
     pub async fn is_empty(&self) -> bool {
     pub async fn is_empty(&self) -> bool {
         self.addrs.lock().await.is_empty()
         self.addrs.lock().await.is_empty()
     }
     }

+ 29 - 6
src/net/message_subscriber.rs

@@ -13,9 +13,12 @@ use crate::net::error::{NetError, NetResult};
 use crate::net::messages::Message;
 use crate::net::messages::Message;
 use crate::serial::{Decodable, Encodable};
 use crate::serial::{Decodable, Encodable};
 
 
+/// 64bit identifier for message subscription.
 pub type MessageSubscriptionID = u64;
 pub type MessageSubscriptionID = u64;
 type MessageResult<M> = NetResult<Arc<M>>;
 type MessageResult<M> = NetResult<Arc<M>>;
 
 
+/// Handles message subscriptions through a subscription ID and a receiver channel.
+/// Inherits from Message Dispatcher. 
 pub struct MessageSubscription<M: Message> {
 pub struct MessageSubscription<M: Message> {
     id: MessageSubscriptionID,
     id: MessageSubscriptionID,
     recv_queue: async_channel::Receiver<MessageResult<M>>,
     recv_queue: async_channel::Receiver<MessageResult<M>>,
@@ -23,6 +26,7 @@ pub struct MessageSubscription<M: Message> {
 }
 }
 
 
 impl<M: Message> MessageSubscription<M> {
 impl<M: Message> MessageSubscription<M> {
+    /// Start receiving messages.
     pub async fn receive(&self) -> MessageResult<M> {
     pub async fn receive(&self) -> MessageResult<M> {
         match self.recv_queue.recv().await {
         match self.recv_queue.recv().await {
             Ok(message) => message,
             Ok(message) => message,
@@ -32,13 +36,14 @@ impl<M: Message> MessageSubscription<M> {
         }
         }
     }
     }
 
 
-    // Must be called manually since async Drop is not possible in Rust
+    /// Unsubscribe from a message subscription. Must be called manually.
     pub async fn unsubscribe(&self) {
     pub async fn unsubscribe(&self) {
         self.parent.clone().unsubscribe(self.id).await
         self.parent.clone().unsubscribe(self.id).await
     }
     }
 }
 }
 
 
 #[async_trait]
 #[async_trait]
+/// Generic interface for message dispatcher. 
 trait MessageDispatcherInterface: Send + Sync {
 trait MessageDispatcherInterface: Send + Sync {
     async fn trigger(&self, payload: Vec<u8>);
     async fn trigger(&self, payload: Vec<u8>);
 
 
@@ -47,22 +52,26 @@ trait MessageDispatcherInterface: Send + Sync {
     fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
     fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
 }
 }
 
 
+/// Maintains a list of active subscribers and handles sending messages across subscriptions.
 struct MessageDispatcher<M: Message> {
 struct MessageDispatcher<M: Message> {
     subs: Mutex<HashMap<MessageSubscriptionID, async_channel::Sender<MessageResult<M>>>>,
     subs: Mutex<HashMap<MessageSubscriptionID, async_channel::Sender<MessageResult<M>>>>,
 }
 }
 
 
 impl<M: Message> MessageDispatcher<M> {
 impl<M: Message> MessageDispatcher<M> {
+    /// Create a new message dispatcher.
     fn new() -> Self {
     fn new() -> Self {
         MessageDispatcher {
         MessageDispatcher {
             subs: Mutex::new(HashMap::new()),
             subs: Mutex::new(HashMap::new()),
         }
         }
     }
     }
 
 
+    /// Create a random ID.
     pub fn random_id() -> MessageSubscriptionID {
     pub fn random_id() -> MessageSubscriptionID {
         let mut rng = rand::thread_rng();
         let mut rng = rand::thread_rng();
         rng.gen()
         rng.gen()
     }
     }
 
 
+    /// Subscribe to a channel. Assigns a new ID and adds it to the list of subscribers.
     pub async fn subscribe(self: Arc<Self>) -> MessageSubscription<M> {
     pub async fn subscribe(self: Arc<Self>) -> MessageSubscription<M> {
         let (sender, recvr) = async_channel::unbounded();
         let (sender, recvr) = async_channel::unbounded();
         let sub_id = Self::random_id();
         let sub_id = Self::random_id();
@@ -75,10 +84,12 @@ impl<M: Message> MessageDispatcher<M> {
         }
         }
     }
     }
 
 
+    /// Unsubcribe from a channel. Removes the associated ID from the subscriber list.
     async fn unsubscribe(&self, sub_id: MessageSubscriptionID) {
     async fn unsubscribe(&self, sub_id: MessageSubscriptionID) {
         self.subs.lock().await.remove(&sub_id);
         self.subs.lock().await.remove(&sub_id);
     }
     }
-
+    
+    /// Send a message to all subscriber channels. Automatically clear inactive channels.
     async fn trigger_all(&self, message: MessageResult<M>) {
     async fn trigger_all(&self, message: MessageResult<M>) {
         debug!(
         debug!(
             "MessageDispatcher<M={}>::trigger_all({}) [START, subs={}]",
             "MessageDispatcher<M={}>::trigger_all({}) [START, subs={}]",
@@ -108,7 +119,8 @@ impl<M: Message> MessageDispatcher<M> {
             self.subs.lock().await.len()
             self.subs.lock().await.len()
         );
         );
     }
     }
-
+    
+    /// Remove inactive channels.
     async fn collect_garbage(&self, ids: Vec<MessageSubscriptionID>) {
     async fn collect_garbage(&self, ids: Vec<MessageSubscriptionID>) {
         let mut subs = self.subs.lock().await;
         let mut subs = self.subs.lock().await;
         for id in &ids {
         for id in &ids {
@@ -118,7 +130,9 @@ impl<M: Message> MessageDispatcher<M> {
 }
 }
 
 
 #[async_trait]
 #[async_trait]
+// Local implementation of the Message Dispatcher Interface.
 impl<M: Message> MessageDispatcherInterface for MessageDispatcher<M> {
 impl<M: Message> MessageDispatcherInterface for MessageDispatcher<M> {
+    /// Deserialize data into a message type.
     async fn trigger(&self, payload: Vec<u8>) {
     async fn trigger(&self, payload: Vec<u8>) {
         // deserialize data into type
         // deserialize data into type
         // send down the pipes
         // send down the pipes
@@ -133,29 +147,34 @@ impl<M: Message> MessageDispatcherInterface for MessageDispatcher<M> {
             }
             }
         }
         }
     }
     }
-
+    
+    /// Sends a message to all subscriber channels. Clears any inactive channels.
     async fn trigger_error(&self, err: NetError) {
     async fn trigger_error(&self, err: NetError) {
         self.trigger_all(Err(err)).await;
         self.trigger_all(Err(err)).await;
     }
     }
 
 
+    /// Converts to Any trait. Enables the dynamic modification of static types.
     fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
     fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
         self
         self
     }
     }
 }
 }
 
 
-// NOTE: this class is a more general version of system::Subscriber which can dispatch
-// multiple different type of registered types to sub-dispatchers
+/// Generic publish/subscribe class that can dispatch any kind of message
+/// to a subscribed list of dispatchers. Dispatchers subscribe to a single message format of any
+/// type. This is a generalized version of the pub/sub model in system::Subscriber. 
 pub struct MessageSubsystem {
 pub struct MessageSubsystem {
     dispatchers: Mutex<HashMap<&'static str, Arc<dyn MessageDispatcherInterface>>>,
     dispatchers: Mutex<HashMap<&'static str, Arc<dyn MessageDispatcherInterface>>>,
 }
 }
 
 
 impl MessageSubsystem {
 impl MessageSubsystem {
+    /// Create a new message subsystem.
     pub fn new() -> Self {
     pub fn new() -> Self {
         MessageSubsystem {
         MessageSubsystem {
             dispatchers: Mutex::new(HashMap::new()),
             dispatchers: Mutex::new(HashMap::new()),
         }
         }
     }
     }
 
 
+    /// Add a new message dispatcher.
     pub async fn add_dispatch<M: Message>(&self) {
     pub async fn add_dispatch<M: Message>(&self) {
         self.dispatchers
         self.dispatchers
             .lock()
             .lock()
@@ -163,6 +182,7 @@ impl MessageSubsystem {
             .insert(M::name(), Arc::new(MessageDispatcher::<M>::new()));
             .insert(M::name(), Arc::new(MessageDispatcher::<M>::new()));
     }
     }
 
 
+    /// Add a dispatcher to the list of subscribers.
     pub async fn subscribe<M: Message>(&self) -> NetResult<MessageSubscription<M>> {
     pub async fn subscribe<M: Message>(&self) -> NetResult<MessageSubscription<M>> {
         let dispatcher = self.dispatchers.lock().await.get(M::name()).cloned();
         let dispatcher = self.dispatchers.lock().await.get(M::name()).cloned();
 
 
@@ -185,6 +205,7 @@ impl MessageSubsystem {
         Ok(sub)
         Ok(sub)
     }
     }
 
 
+    /// Sends a message out to subscribers. Returns an error if the message doesn't send.
     pub async fn notify(&self, command: &str, payload: Vec<u8>) {
     pub async fn notify(&self, command: &str, payload: Vec<u8>) {
         let dispatcher = self.dispatchers.lock().await.get(command).cloned();
         let dispatcher = self.dispatchers.lock().await.get(command).cloned();
 
 
@@ -201,6 +222,7 @@ impl MessageSubsystem {
         }
         }
     }
     }
 
 
+    /// Send a message to all subscriber channels. Clear any inactive channels.
     pub async fn trigger_error(&self, err: NetError) {
     pub async fn trigger_error(&self, err: NetError) {
         // TODO: this could be parallelized
         // TODO: this could be parallelized
         for dispatcher in self.dispatchers.lock().await.values() {
         for dispatcher in self.dispatchers.lock().await.values() {
@@ -209,6 +231,7 @@ impl MessageSubsystem {
     }
     }
 }
 }
 
 
+/// Test functions for message subsystem.
 // This is a test function for the message subsystem code above
 // This is a test function for the message subsystem code above
 // Normall we would use the #[test] macro but cannot since it is async code
 // Normall we would use the #[test] macro but cannot since it is async code
 // Instead we call it using smol::block_on() in the unit test code after this func
 // Instead we call it using smol::block_on() in the unit test code after this func

+ 11 - 2
src/net/messages.rs

@@ -8,26 +8,33 @@ use crate::serial::{Decodable, Encodable, VarInt};
 
 
 const MAGIC_BYTES: [u8; 4] = [0xd9, 0xef, 0xb6, 0x7d];
 const MAGIC_BYTES: [u8; 4] = [0xd9, 0xef, 0xb6, 0x7d];
 
 
+/// Generic message template.
 pub trait Message: 'static + Encodable + Decodable + Send + Sync {
 pub trait Message: 'static + Encodable + Decodable + Send + Sync {
     fn name() -> &'static str;
     fn name() -> &'static str;
 }
 }
 
 
+/// Outbound keep-alive message.
 pub struct PingMessage {
 pub struct PingMessage {
     pub nonce: u32,
     pub nonce: u32,
 }
 }
 
 
+/// Inbound keep-alive message.
 pub struct PongMessage {
 pub struct PongMessage {
     pub nonce: u32,
     pub nonce: u32,
 }
 }
 
 
+/// Requests address of outbound connection. 
 pub struct GetAddrsMessage {}
 pub struct GetAddrsMessage {}
 
 
+/// Sends address information to inbound connection. Response to GetAddrs message.
 pub struct AddrsMessage {
 pub struct AddrsMessage {
     pub addrs: Vec<SocketAddr>,
     pub addrs: Vec<SocketAddr>,
 }
 }
 
 
+/// Requests version information of outbound connection.
 pub struct VersionMessage {}
 pub struct VersionMessage {}
 
 
+/// Sends version information to inbound connection. Response to VersionMessage.
 pub struct VerackMessage {}
 pub struct VerackMessage {}
 
 
 impl Message for PingMessage {
 impl Message for PingMessage {
@@ -151,13 +158,14 @@ impl Decodable for VerackMessage {
     }
     }
 }
 }
 
 
-// Packets are the base type read from the network
-// These are converted to messages and passed to event loop
+/// Packets are the base type read from the network. Converted to messages and passed to event
+/// loop.
 pub struct Packet {
 pub struct Packet {
     pub command: String,
     pub command: String,
     pub payload: Vec<u8>,
     pub payload: Vec<u8>,
 }
 }
 
 
+/// Reads and decodes an inbound payload.
 pub async fn read_packet<R: AsyncRead + Unpin>(stream: &mut R) -> Result<Packet> {
 pub async fn read_packet<R: AsyncRead + Unpin>(stream: &mut R) -> Result<Packet> {
     // Packets have a 4 byte header of magic digits
     // Packets have a 4 byte header of magic digits
     // This is used for network debugging
     // This is used for network debugging
@@ -193,6 +201,7 @@ pub async fn read_packet<R: AsyncRead + Unpin>(stream: &mut R) -> Result<Packet>
     })
     })
 }
 }
 
 
+/// Sends an outbound packet by writing data to TCP stream.
 pub async fn send_packet<W: AsyncWrite + Unpin>(stream: &mut W, packet: Packet) -> Result<()> {
 pub async fn send_packet<W: AsyncWrite + Unpin>(stream: &mut W, packet: Packet) -> Result<()> {
     debug!(target: "net", "sending magic...");
     debug!(target: "net", "sending magic...");
     stream.write_all(&MAGIC_BYTES).await?;
     stream.write_all(&MAGIC_BYTES).await?;

+ 18 - 3
src/net/p2p.rs

@@ -10,11 +10,14 @@ use crate::net::sessions::{InboundSession, OutboundSession, SeedSession};
 use crate::net::{Channel, ChannelPtr, Hosts, HostsPtr, Settings, SettingsPtr};
 use crate::net::{Channel, ChannelPtr, Hosts, HostsPtr, Settings, SettingsPtr};
 use crate::system::{Subscriber, SubscriberPtr, Subscription};
 use crate::system::{Subscriber, SubscriberPtr, Subscription};
 
 
+/// List of channels that are awaiting connection.
 pub type PendingChannels = Mutex<HashSet<SocketAddr>>;
 pub type PendingChannels = Mutex<HashSet<SocketAddr>>;
+/// List of connected channels.
 pub type ConnectedChannels<T> = Mutex<HashMap<SocketAddr, Arc<T>>>;
 pub type ConnectedChannels<T> = Mutex<HashMap<SocketAddr, Arc<T>>>;
-
+/// Atomic pointer to p2p interface.
 pub type P2pPtr = Arc<P2p>;
 pub type P2pPtr = Arc<P2p>;
 
 
+/// Top level peer-to-peer networking interface. 
 pub struct P2p {
 pub struct P2p {
     pending: PendingChannels,
     pending: PendingChannels,
     channels: ConnectedChannels<Channel>,
     channels: ConnectedChannels<Channel>,
@@ -26,6 +29,7 @@ pub struct P2p {
 }
 }
 
 
 impl P2p {
 impl P2p {
+    /// Create a new p2p network.
     pub fn new(settings: Settings) -> Arc<Self> {
     pub fn new(settings: Settings) -> Arc<Self> {
         let settings = Arc::new(settings);
         let settings = Arc::new(settings);
         Arc::new(Self {
         Arc::new(Self {
@@ -74,7 +78,7 @@ impl P2p {
         debug!(target: "net", "P2p::run() [BEGIN]");
         debug!(target: "net", "P2p::run() [BEGIN]");
         Ok(())
         Ok(())
     }
     }
-
+    /// Add channel address to the list of connected channels.
     pub async fn store(&self, channel: ChannelPtr) {
     pub async fn store(&self, channel: ChannelPtr) {
         self.channels
         self.channels
             .lock()
             .lock()
@@ -82,37 +86,48 @@ impl P2p {
             .insert(channel.address(), channel.clone());
             .insert(channel.address(), channel.clone());
         self.channel_subscriber.notify(Ok(channel)).await;
         self.channel_subscriber.notify(Ok(channel)).await;
     }
     }
+
+    /// Remove a channel from the list of connected channels.
     pub async fn remove(&self, channel: ChannelPtr) {
     pub async fn remove(&self, channel: ChannelPtr) {
         self.channels.lock().await.remove(&channel.address());
         self.channels.lock().await.remove(&channel.address());
     }
     }
 
 
+    /// Check whether a channel is stored in the list of channels.
     pub async fn exists(&self, addr: &SocketAddr) -> bool {
     pub async fn exists(&self, addr: &SocketAddr) -> bool {
         self.channels.lock().await.contains_key(addr)
         self.channels.lock().await.contains_key(addr)
     }
     }
 
 
+    /// Add a channel to the list of pending channels.
     pub async fn add_pending(&self, addr: SocketAddr) -> bool {
     pub async fn add_pending(&self, addr: SocketAddr) -> bool {
         self.pending.lock().await.insert(addr)
         self.pending.lock().await.insert(addr)
     }
     }
+
+    /// Remove a channel from the list of pending channels.
     pub async fn remove_pending(&self, addr: &SocketAddr) {
     pub async fn remove_pending(&self, addr: &SocketAddr) {
         self.pending.lock().await.remove(addr);
         self.pending.lock().await.remove(addr);
     }
     }
 
 
+    /// Return the number of connected channels.
     pub async fn connections_count(&self) -> usize {
     pub async fn connections_count(&self) -> usize {
         self.channels.lock().await.len()
         self.channels.lock().await.len()
     }
     }
 
 
+    /// Return an atomic pointer to the default network settings.
     pub fn settings(&self) -> SettingsPtr {
     pub fn settings(&self) -> SettingsPtr {
         self.settings.clone()
         self.settings.clone()
     }
     }
 
 
+    /// Return an atomic pointer to the list of hosts.
     pub fn hosts(&self) -> HostsPtr {
     pub fn hosts(&self) -> HostsPtr {
         self.hosts.clone()
         self.hosts.clone()
     }
     }
 
 
+    /// Subscribe to a channel.
     pub async fn subscribe_channel(&self) -> Subscription<NetResult<ChannelPtr>> {
     pub async fn subscribe_channel(&self) -> Subscription<NetResult<ChannelPtr>> {
         self.channel_subscriber.clone().subscribe().await
         self.channel_subscriber.clone().subscribe().await
     }
     }
-
+    
+    /// Stop a subscription.
     pub async fn subscribe_stop(&self) -> Subscription<NetError> {
     pub async fn subscribe_stop(&self) -> Subscription<NetError> {
         self.stop_subscriber.clone().subscribe().await
         self.stop_subscriber.clone().subscribe().await
     }
     }

+ 6 - 4
src/net/protocols/protocol_version.rs

@@ -9,6 +9,7 @@ use crate::net::messages;
 use crate::net::utility::sleep;
 use crate::net::utility::sleep;
 use crate::net::{ChannelPtr, SettingsPtr};
 use crate::net::{ChannelPtr, SettingsPtr};
 
 
+/// Version information sent between nodes at the start of a connection.
 pub struct ProtocolVersion {
 pub struct ProtocolVersion {
     channel: ChannelPtr,
     channel: ChannelPtr,
     version_sub: MessageSubscription<messages::VersionMessage>,
     version_sub: MessageSubscription<messages::VersionMessage>,
@@ -17,6 +18,7 @@ pub struct ProtocolVersion {
 }
 }
 
 
 impl ProtocolVersion {
 impl ProtocolVersion {
+    /// Create a new version instance.
     pub async fn new(channel: ChannelPtr, settings: SettingsPtr) -> Arc<Self> {
     pub async fn new(channel: ChannelPtr, settings: SettingsPtr) -> Arc<Self> {
         let version_sub = channel
         let version_sub = channel
             .clone()
             .clone()
@@ -37,7 +39,7 @@ impl ProtocolVersion {
             settings,
             settings,
         })
         })
     }
     }
-
+    /// Start version information exchange.
     pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
     pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
         debug!(target: "net", "ProtocolVersion::run() [START]");
         debug!(target: "net", "ProtocolVersion::run() [START]");
         // Start timer
         // Start timer
@@ -51,7 +53,7 @@ impl ProtocolVersion {
         debug!(target: "net", "ProtocolVersion::run() [END]");
         debug!(target: "net", "ProtocolVersion::run() [END]");
         result
         result
     }
     }
-
+    /// Send and recieve version information.
     async fn exchange_versions(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
     async fn exchange_versions(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
         debug!(target: "net", "ProtocolVersion::exchange_versions() [START]");
         debug!(target: "net", "ProtocolVersion::exchange_versions() [START]");
 
 
@@ -62,7 +64,7 @@ impl ProtocolVersion {
         debug!(target: "net", "ProtocolVersion::exchange_versions() [END]");
         debug!(target: "net", "ProtocolVersion::exchange_versions() [END]");
         Ok(())
         Ok(())
     }
     }
-
+    /// Send version info and wait for version acknowledgement.
     async fn send_version(self: Arc<Self>) -> NetResult<()> {
     async fn send_version(self: Arc<Self>) -> NetResult<()> {
         debug!(target: "net", "ProtocolVersion::send_version() [START]");
         debug!(target: "net", "ProtocolVersion::send_version() [START]");
         let version = messages::VersionMessage {};
         let version = messages::VersionMessage {};
@@ -74,7 +76,7 @@ impl ProtocolVersion {
         debug!(target: "net", "ProtocolVersion::send_version() [END]");
         debug!(target: "net", "ProtocolVersion::send_version() [END]");
         Ok(())
         Ok(())
     }
     }
-
+    /// Recieve version info and send version acknowledgement.
     async fn recv_version(self: Arc<Self>) -> NetResult<()> {
     async fn recv_version(self: Arc<Self>) -> NetResult<()> {
         debug!(target: "net", "ProtocolVersion::recv_version() [START]");
         debug!(target: "net", "ProtocolVersion::recv_version() [START]");
         let _version_msg = self.version_sub.receive().await?;
         let _version_msg = self.version_sub.receive().await?;

+ 5 - 3
src/net/sessions/inbound_session.rs

@@ -10,6 +10,7 @@ use crate::net::{Acceptor, AcceptorPtr};
 use crate::net::{ChannelPtr, P2p};
 use crate::net::{ChannelPtr, P2p};
 use crate::system::{StoppableTask, StoppableTaskPtr};
 use crate::system::{StoppableTask, StoppableTaskPtr};
 
 
+/// Inbound connections session.
 pub struct InboundSession {
 pub struct InboundSession {
     p2p: Weak<P2p>,
     p2p: Weak<P2p>,
     acceptor: AcceptorPtr,
     acceptor: AcceptorPtr,
@@ -17,6 +18,7 @@ pub struct InboundSession {
 }
 }
 
 
 impl InboundSession {
 impl InboundSession {
+    /// Create a new inbound session.
     pub fn new(p2p: Weak<P2p>) -> Arc<Self> {
     pub fn new(p2p: Weak<P2p>) -> Arc<Self> {
         let acceptor = Acceptor::new();
         let acceptor = Acceptor::new();
 
 
@@ -26,7 +28,7 @@ impl InboundSession {
             accept_task: StoppableTask::new(),
             accept_task: StoppableTask::new(),
         })
         })
     }
     }
-
+    /// Start the inbound session.
     pub fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
     pub fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
         match self.p2p().settings().inbound {
         match self.p2p().settings().inbound {
             Some(accept_addr) => {
             Some(accept_addr) => {
@@ -49,12 +51,12 @@ impl InboundSession {
 
 
         Ok(())
         Ok(())
     }
     }
-
+    /// Stop the inbound session.
     pub async fn stop(&self) {
     pub async fn stop(&self) {
         self.acceptor.stop().await;
         self.acceptor.stop().await;
         self.accept_task.stop().await;
         self.accept_task.stop().await;
     }
     }
-
+    /// Start accepting connections for inbound session.
     fn start_accept_session(
     fn start_accept_session(
         self: Arc<Self>,
         self: Arc<Self>,
         accept_addr: SocketAddr,
         accept_addr: SocketAddr,

+ 6 - 2
src/net/sessions/outbound_session.rs

@@ -10,19 +10,21 @@ use crate::net::sessions::Session;
 use crate::net::{ChannelPtr, Connector, P2p};
 use crate::net::{ChannelPtr, Connector, P2p};
 use crate::system::{StoppableTask, StoppableTaskPtr};
 use crate::system::{StoppableTask, StoppableTaskPtr};
 
 
+/// Outbound connections session.
 pub struct OutboundSession {
 pub struct OutboundSession {
     p2p: Weak<P2p>,
     p2p: Weak<P2p>,
     connect_slots: Mutex<Vec<StoppableTaskPtr>>,
     connect_slots: Mutex<Vec<StoppableTaskPtr>>,
 }
 }
 
 
 impl OutboundSession {
 impl OutboundSession {
+    /// Create a new outbound session.
     pub fn new(p2p: Weak<P2p>) -> Arc<Self> {
     pub fn new(p2p: Weak<P2p>) -> Arc<Self> {
         Arc::new(Self {
         Arc::new(Self {
             p2p,
             p2p,
             connect_slots: Mutex::new(Vec::new()),
             connect_slots: Mutex::new(Vec::new()),
         })
         })
     }
     }
-
+    /// Start the outbound session.
     pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
     pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
         let slots_count = self.p2p().settings().outbound_connections;
         let slots_count = self.p2p().settings().outbound_connections;
         info!("Starting {} outbound connection slots.", slots_count);
         info!("Starting {} outbound connection slots.", slots_count);
@@ -45,6 +47,7 @@ impl OutboundSession {
         Ok(())
         Ok(())
     }
     }
 
 
+    /// Stop the inbound session.
     pub async fn stop(&self) {
     pub async fn stop(&self) {
         let connect_slots = &*self.connect_slots.lock().await;
         let connect_slots = &*self.connect_slots.lock().await;
 
 
@@ -53,6 +56,7 @@ impl OutboundSession {
         }
         }
     }
     }
 
 
+    /// Start making outbound connections.
     pub async fn channel_connect_loop(
     pub async fn channel_connect_loop(
         self: Arc<Self>,
         self: Arc<Self>,
         slot_number: u32,
         slot_number: u32,
@@ -132,7 +136,7 @@ impl OutboundSession {
             return Ok(addr);
             return Ok(addr);
         }
         }
     }
     }
-
+    /// Check whether an inbound address is configured.
     fn addr_is_inbound(addr: &SocketAddr, inbound_addr: &Option<SocketAddr>) -> bool {
     fn addr_is_inbound(addr: &SocketAddr, inbound_addr: &Option<SocketAddr>) -> bool {
         match inbound_addr {
         match inbound_addr {
             Some(inbound_addr) => inbound_addr == addr,
             Some(inbound_addr) => inbound_addr == addr,

+ 3 - 0
src/net/sessions/seed_session.rs

@@ -10,15 +10,18 @@ use crate::net::sessions::Session;
 use crate::net::utility::sleep;
 use crate::net::utility::sleep;
 use crate::net::{ChannelPtr, Connector, HostsPtr, P2p, SettingsPtr};
 use crate::net::{ChannelPtr, Connector, HostsPtr, P2p, SettingsPtr};
 
 
+/// Seed connections session.
 pub struct SeedSession {
 pub struct SeedSession {
     p2p: Weak<P2p>,
     p2p: Weak<P2p>,
 }
 }
 
 
 impl SeedSession {
 impl SeedSession {
+    /// Create a new seed session instance.
     pub fn new(p2p: Weak<P2p>) -> Arc<Self> {
     pub fn new(p2p: Weak<P2p>) -> Arc<Self> {
         Arc::new(Self { p2p })
         Arc::new(Self { p2p })
     }
     }
 
 
+    /// Start the seed session.
     pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
     pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
         debug!(target: "net", "SeedSession::start() [START]");
         debug!(target: "net", "SeedSession::start() [START]");
         let settings = self.p2p().settings();
         let settings = self.p2p().settings();

+ 1 - 0
src/net/sessions/session.rs

@@ -25,6 +25,7 @@ async fn remove_sub_on_stop(p2p: P2pPtr, channel: ChannelPtr) {
 
 
 #[async_trait]
 #[async_trait]
 pub trait Session: Sync {
 pub trait Session: Sync {
+    /// Register a new channel with the session.
     async fn register_channel(
     async fn register_channel(
         self: Arc<Self>,
         self: Arc<Self>,
         channel: ChannelPtr,
         channel: ChannelPtr,

+ 2 - 0
src/net/settings.rs

@@ -1,8 +1,10 @@
 use std::net::SocketAddr;
 use std::net::SocketAddr;
 use std::sync::Arc;
 use std::sync::Arc;
 
 
+/// Atomic pointer to network settings.
 pub type SettingsPtr = Arc<Settings>;
 pub type SettingsPtr = Arc<Settings>;
 
 
+/// Default network configuration settings.
 #[derive(Clone)]
 #[derive(Clone)]
 pub struct Settings {
 pub struct Settings {
     pub inbound: Option<SocketAddr>,
     pub inbound: Option<SocketAddr>,

+ 1 - 0
src/net/utility.rs

@@ -1,6 +1,7 @@
 use smol::Timer;
 use smol::Timer;
 use std::time::Duration;
 use std::time::Duration;
 
 
+/// Sleep for any number of seconds.
 pub async fn sleep(seconds: u32) {
 pub async fn sleep(seconds: u32) {
     Timer::after(Duration::from_secs(seconds.into())).await;
     Timer::after(Duration::from_secs(seconds.into())).await;
 }
 }