d3_components/net_instruction_set.rs
1#![allow(dead_code)]
2use super::*;
3// ```sequence
4// Alice->Net: BindListner(addres, Alice:sender)
5// note right of Alice: Alice waits for a connection
6// Net->Alice: NewConn(conn_id, local, remote, write_buf_size)
7// note right of Alice: Alice is told of the connection
8// and has Bob handle it
9// Alice->Net: BindConn(conn_id, Bob:sender)
10// note left of Bob: Bob waits for bytes
11// Net->Bob: RecvBytes(conn_id, bytes)
12// note left of Bob: Bob sends some bytes
13// Bob->Net: SendBytes(conn_id, bytes)
14// note left of Bob: Bob may be told how
15// much more he can send
16// Net->Bob: SendReady(write_buf_size)
17// note left of Bob: Bob Closes the connection
18// Bob->Net: Close(conn_id)
19// ```
20
21/// This is where d3 meets Tcp or UDP. The Network leans heavily upon Mio
22/// to provide the foundation for interacting with the network. The d3 network provides
23/// an additional abstraction to adapt it for d3 machines and encapsulate Mio.
24///
25/// This sequence diagram illustrates a machine, Alice asking for a TCP listener to
26/// be installed. When there is a connection, the network is told to send control
27/// and data commands to the machine Bob.
28///
29/// ```text
30/// +-------+ +-----+ +-----+
31/// | Alice | | Net | | Bob |
32/// +-------+ +-----+ +-----+
33/// | | |
34/// | BindListner(addres, Alice:sender) | |
35/// |--------------------------------------------------->| |
36/// | -------------------------------\ | |
37/// |-| Alice waits for a connection | | |
38/// | |------------------------------| | |
39/// | | |
40/// | NewConn(conn_id, local, remote, write_buf_size) | |
41/// |<---------------------------------------------------| |
42/// | ----------------------------------\ | |
43/// |-| Alice is told of the connection | | |
44/// | | and has Bob handle it | | |
45/// | |---------------------------------| | |
46/// | BindConn(conn_id, Bob:sender) | |
47/// |--------------------------------------------------->| |
48/// | | ----------------------\ |
49/// | | | Bob waits for bytes |-|
50/// | | |---------------------| |
51/// | | |
52/// | | RecvBytes(conn_id, bytes) |
53/// | |----------------------------->|
54/// | | -----------------------\ |
55/// | | | Bob sends some bytes |-|
56/// | | |----------------------| |
57/// | | |
58/// | | SendBytes(conn_id, bytes) |
59/// | |<-----------------------------|
60/// | | ------------------------\ |
61/// | | | Bob may be told how |-|
62/// | | | much more he can send | |
63/// | | |-----------------------| |
64/// | | SendReady(write_buf_size) |
65/// | |----------------------------->|
66/// | |----------------------------\ |
67/// | || Bob Closes the connection |-|
68/// | ||---------------------------| |
69/// | | |
70/// | | Close(conn_id) |
71/// | |<-----------------------------|
72/// | | |
73/// ```
74///
75/// UDP is a bit simpler, as illusted by the following sequence diagram. Alice asks the
76/// network to bind a UDP address. Whenever a packet arrives it is sent to Alice. Alice
77/// can send a packet to the network too. Although there isn't a connection, in the network
78/// sense, a conn_id is used, for both parity and as a shorthand for the local address.
79///
80/// ```text
81/// +-------+ +-----+
82/// | Alice | | Net |
83/// +-------+ +-----+
84/// | |
85/// | BindUdpListener(address, Alice:sender) |
86/// |------------------------------------------>|
87/// | ------------------------------\ |
88/// |-| Wait for a packet to arrive | |
89/// | |-----------------------------| |
90/// | |
91/// | RecvPkt(conn_id, local, remote, bytes) |
92/// |<------------------------------------------|
93/// | -----------------------\ |
94/// |-| Alice sends a packet | |
95/// | |----------------------| |
96/// | |
97/// | SendPkt(conn_id, remote, bytes) |
98/// |------------------------------------------>|
99/// | |
100/// ```
101#[derive(Debug, MachineImpl)]
102pub enum NetCmd {
103 /// Stop the network. Stop is used in conjuntion with starting and stopping the
104 /// Server and Network.
105 Stop,
106 /// Binds a TCP listener to an address, notifying the sender when a connection is accepted.
107 BindListener(String, NetSender),
108 /// Bind a UDP listener to an address, notifying the sender when a connection is accepted.
109 BindUdpListener(String, NetSender),
110 /// New connection notification (connection_id, bind_addr,
111 /// connect_from, max_byte) are sent to the sender regitered via the BindListener.
112 NewConn(NetConnId, String, String, usize),
113 /// BindConn starts the flow of information (connection_id, sender) between the network and
114 /// a sender.
115 BindConn(NetConnId, NetSender),
116 /// When sent to the network, CloseConn closes the connection, also known as a local close.
117 /// When received by the BindConn listener, CloseConn is notification that the connection
118 /// has been closed, also known as a remote close.
119 CloseConn(NetConnId),
120 /// Sent to the BindConn sender, RecvBytes provides bytes read from the connection.
121 RecvBytes(NetConnId, Vec<u8>),
122 /// Sent to UDP listener
123 /// socket id, destination, source, bytes
124 RecvPkt(NetConnId, String, String, Vec<u8>),
125 /// Sent to the network, SendBytes provides bytes to be written to the network.
126 SendBytes(NetConnId, Vec<u8>),
127 /// Send UDP packet to network
128 /// socket id, destination, bytes
129 SendPkt(NetConnId, String, Vec<u8>),
130 /// Sent to the BindConn sender, it provides an update to the number of bytes
131 /// available for writing to the network. A use case for this would be providing
132 /// feedback for throttling data being generated for a connection.
133 SendReady(NetConnId, usize),
134}
135/// A network connection is always expressed as a NetConnId and identifies a specific
136/// network connection.
137pub type NetConnId = usize;
138/// Shorthand for a sender, that can be sent NetCmd instructions.
139pub type NetSender = Sender<NetCmd>;