1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
#![allow(dead_code)]
use super::*;
// ```sequence
// Alice->Net: BindListner(addres, Alice:sender)
// note right of Alice: Alice waits for a connection
// Net->Alice: NewConn(conn_id, local, remote, write_buf_size)
// note right of Alice: Alice is told of the connection
// and has Bob handle it
// Alice->Net: BindConn(conn_id, Bob:sender)
// note left of Bob: Bob waits for bytes
// Net->Bob: RecvBytes(conn_id, bytes)
// note left of Bob: Bob sends some bytes
// Bob->Net: SendBytes(conn_id, bytes)
// note left of Bob: Bob may be told how
// much more he can send
// Net->Bob: SendReady(write_buf_size)
// note left of Bob: Bob Closes the connection
// Bob->Net: Close(conn_id)
// ```

/// This is where d3 meets Tcp (Udp to follow). The Network leans heavily upon Mio
/// to provide the foundation for interacting with the network. The d3 network provides
/// an additional abstraction to adapt it for d3 machines and encapsulate Mio.
///
/// This sequence diagram illustrates a machine, Alice asking for a listener to
/// be installed. When there is a connection, the network is told to send control
/// and data commands to the machine Bob.
///
/// ```text
/// +-------+                                             +-----+                        +-----+
/// | Alice |                                             | Net |                        | Bob |
/// +-------+                                             +-----+                        +-----+
///    |                                                    |                              |
///    | BindListner(addres, Alice:sender)                  |                              |
///    |--------------------------------------------------->|                              |
///    | -------------------------------\                   |                              |
///    |-| Alice waits for a connection |                   |                              |
///    | |------------------------------|                   |                              |
///    |                                                    |                              |
///    |    NewConn(conn_id, local, remote, write_buf_size) |                              |
///    |<---------------------------------------------------|                              |
///    | ----------------------------------\                |                              |
///    |-| Alice is told of the connection |                |                              |
///    | | and has Bob handle it           |                |                              |
///    | |---------------------------------|                |                              |
///    | BindConn(conn_id, Bob:sender)                      |                              |
///    |--------------------------------------------------->|                              |
///    |                                                    |      ----------------------\ |
///    |                                                    |      | Bob waits for bytes |-|
///    |                                                    |      |---------------------| |
///    |                                                    |                              |
///    |                                                    | RecvBytes(conn_id, bytes)    |
///    |                                                    |----------------------------->|
///    |                                                    |     -----------------------\ |
///    |                                                    |     | Bob sends some bytes |-|
///    |                                                    |     |----------------------| |
///    |                                                    |                              |
///    |                                                    |    SendBytes(conn_id, bytes) |
///    |                                                    |<-----------------------------|
///    |                                                    |    ------------------------\ |
///    |                                                    |    | Bob may be told how   |-|
///    |                                                    |    | much more he can send | |
///    |                                                    |    |-----------------------| |
///    |                                                    | SendReady(write_buf_size)    |
///    |                                                    |----------------------------->|
///    |                                                    |----------------------------\ |
///    |                                                    || Bob Closes the connection |-|
///    |                                                    ||---------------------------| |
///    |                                                    |                              |
///    |                                                    |               Close(conn_id) |
///    |                                                    |<-----------------------------|
///    |                                                    |                              |
/// ```
#[derive(Debug, MachineImpl)]
pub enum NetCmd {
    /// Stop the network. Stop is used in conjuntion with starting and stopping the
    /// Server and Network.
    Stop,
    /// Binds a TCP listener to an address, notifying the sender when a connection is accepted.
    BindListener(String, NetSender),
    /// New connection notification (connection_id, bind_addr,
    /// connect_from, max_byte) are sent to the sender regitered via the BindListener.
    NewConn(NetConnId, String, String, usize),
    /// BindConn starts the flow of information (connection_id, sender) between the network and
    /// a sender.
    BindConn(NetConnId, NetSender),
    /// When sent to the network, CloseConn closes the connection, also known as a local close.
    /// When received by the BindConn listener, CloseConn is notification that the connection
    /// has been closed, also known as a remote close.
    CloseConn(NetConnId),
    /// Sent to the BindConn sender, RecvBytes provides bytes read from the connection.
    RecvBytes(NetConnId, Vec<u8>),
    /// Sent to the network, SendBytes provides bytes to be written to the network.
    SendBytes(NetConnId, Vec<u8>),
    /// Sent to the BindConn sender, it provides an update to the number of bytes
    /// availbe for writing to the network. A use case for this would be providing
    /// feedback for throttling data being generated for a connection.
    SendReady(NetConnId, usize),
}
/// A network connection is always expressed as a NetConnId and identifies a specific
/// network connection.
pub type NetConnId = usize;
/// Shorthand for a sender, that can be sent NetCmd instructions.
pub type NetSender = Sender<NetCmd>;