pub struct Net {
pub graph: Graph,
/* private fields */
}Expand description
The runtime state of a flow-based network.
A Net is created from a Graph and tracks:
- All packets and their locations
- All epochs and their states
- Which epochs are startable
All mutations must go through Net::do_action to ensure proper event tracking.
Fields§
§graph: GraphThe graph topology this network is running on.
Implementations§
Source§impl Net
impl Net
Sourcepub fn new(graph: Graph) -> Self
pub fn new(graph: Graph) -> Self
Creates a new Net from a Graph.
Initializes packet location tracking for all edges and input ports.
Examples found in repository?
examples/diamond_flow.rs (line 30)
24fn main() {
25 // Create a diamond graph
26 let graph = create_diamond_graph();
27 println!("Created diamond graph: A -> B,C -> D");
28 println!("D requires inputs from BOTH B and C\n");
29
30 let mut net = Net::new(graph);
31
32 // Create two packets and place them on edges from A
33 let packet1 = create_packet(&mut net);
34 let packet2 = create_packet(&mut net);
35 println!("Created packets: {} and {}", packet1, packet2);
36
37 // Place packet1 on edge A -> B
38 let edge_a_b = edge_location("A", "out1", "B", "in");
39 net.do_action(&NetAction::TransportPacketToLocation(packet1.clone(), edge_a_b));
40 println!("Placed packet1 on edge A -> B");
41
42 // Place packet2 on edge A -> C
43 let edge_a_c = edge_location("A", "out2", "C", "in");
44 net.do_action(&NetAction::TransportPacketToLocation(packet2.clone(), edge_a_c));
45 println!("Placed packet2 on edge A -> C");
46
47 // Run network - packets move to B and C, triggering epochs
48 net.do_action(&NetAction::RunNetUntilBlocked);
49
50 let startable = net.get_startable_epochs();
51 println!("\nAfter first run: {} startable epochs (B and C)", startable.len());
52
53 // Process B and C, sending outputs to D
54 for epoch_id in startable {
55 let epoch = net.get_epoch(&epoch_id).unwrap();
56 let node_name = epoch.node_name.clone();
57 println!("\nProcessing node {}", node_name);
58
59 // Start the epoch
60 let started = match net.do_action(&NetAction::StartEpoch(epoch_id.clone())) {
61 NetActionResponse::Success(NetActionResponseData::StartedEpoch(e), _) => e,
62 _ => panic!("Failed to start epoch"),
63 };
64
65 // Find and consume the input packet
66 let input_packet = started.in_salvo.packets[0].1.clone();
67 net.do_action(&NetAction::ConsumePacket(input_packet));
68
69 // Create output packet
70 let output = create_packet_in_epoch(&mut net, &started.id);
71
72 // Load into output port and send
73 net.do_action(&NetAction::LoadPacketIntoOutputPort(output, "out".to_string()));
74 net.do_action(&NetAction::SendOutputSalvo(started.id.clone(), "default".to_string()));
75
76 // Finish epoch
77 net.do_action(&NetAction::FinishEpoch(started.id));
78 println!(" Finished {} - sent packet to D", node_name);
79 }
80
81 // Run network - packets move from B->D and C->D edges to D's input ports
82 net.do_action(&NetAction::RunNetUntilBlocked);
83
84 // Check D's input ports
85 let d_in1 = PacketLocation::InputPort("D".to_string(), "in1".to_string());
86 let d_in2 = PacketLocation::InputPort("D".to_string(), "in2".to_string());
87 println!("\nD's input ports:");
88 println!(" in1 (from B): {} packets", net.packet_count_at(&d_in1));
89 println!(" in2 (from C): {} packets", net.packet_count_at(&d_in2));
90
91 // D should now have a startable epoch (both inputs present)
92 let startable_d = net.get_startable_epochs();
93 println!("\nStartable epochs at D: {}", startable_d.len());
94
95 if let Some(d_epoch_id) = startable_d.first() {
96 let d_epoch = net.get_epoch(d_epoch_id).unwrap();
97 println!("D's epoch received {} packets from both branches!", d_epoch.in_salvo.packets.len());
98 }
99
100 println!("\nDiamond flow example complete!");
101}More examples
examples/linear_flow.rs (line 25)
19fn main() {
20 // Create a linear graph: A -> B -> C
21 let graph = create_linear_graph();
22 println!("Created graph with {} nodes", graph.nodes().len());
23
24 // Create a network from the graph
25 let mut net = Net::new(graph);
26
27 // Create a packet outside the network
28 let packet_id = match net.do_action(&NetAction::CreatePacket(None)) {
29 NetActionResponse::Success(NetActionResponseData::Packet(id), _) => {
30 println!("Created packet: {}", id);
31 id
32 }
33 _ => panic!("Failed to create packet"),
34 };
35
36 // Transport packet to the edge A -> B
37 let edge_a_b = PacketLocation::Edge(Edge {
38 source: PortRef {
39 node_name: "A".to_string(),
40 port_type: PortType::Output,
41 port_name: "out".to_string(),
42 },
43 target: PortRef {
44 node_name: "B".to_string(),
45 port_type: PortType::Input,
46 port_name: "in".to_string(),
47 },
48 });
49 net.do_action(&NetAction::TransportPacketToLocation(packet_id.clone(), edge_a_b));
50 println!("Placed packet on edge A -> B");
51
52 // Run the network - packet moves to B's input port and triggers an epoch
53 net.do_action(&NetAction::RunNetUntilBlocked);
54 println!("Ran network until blocked");
55
56 // Check for startable epochs
57 let startable = net.get_startable_epochs();
58 println!("Startable epochs: {}", startable.len());
59
60 if let Some(epoch_id) = startable.first() {
61 // Start the epoch
62 match net.do_action(&NetAction::StartEpoch(epoch_id.clone())) {
63 NetActionResponse::Success(NetActionResponseData::StartedEpoch(epoch), _) => {
64 println!("Started epoch {} on node {}", epoch.id, epoch.node_name);
65
66 // In a real scenario, external code would process the packet here
67 // For this example, we'll just consume it and create an output
68
69 // Consume the input packet
70 net.do_action(&NetAction::ConsumePacket(packet_id));
71 println!("Consumed input packet");
72
73 // Create an output packet
74 let output_packet = match net.do_action(&NetAction::CreatePacket(Some(epoch.id.clone()))) {
75 NetActionResponse::Success(NetActionResponseData::Packet(id), _) => id,
76 _ => panic!("Failed to create output packet"),
77 };
78 println!("Created output packet: {}", output_packet);
79
80 // Load it into the output port
81 net.do_action(&NetAction::LoadPacketIntoOutputPort(output_packet.clone(), "out".to_string()));
82 println!("Loaded packet into output port");
83
84 // Send the output salvo
85 net.do_action(&NetAction::SendOutputSalvo(epoch.id.clone(), "default".to_string()));
86 println!("Sent output salvo - packet is now on edge B -> C");
87
88 // Finish the epoch
89 net.do_action(&NetAction::FinishEpoch(epoch.id));
90 println!("Finished epoch");
91
92 // Run the network again - packet moves to C
93 net.do_action(&NetAction::RunNetUntilBlocked);
94 println!("Ran network until blocked again");
95
96 // Check for new startable epochs at C
97 let startable_c = net.get_startable_epochs();
98 println!("New startable epochs (should be at C): {}", startable_c.len());
99 }
100 _ => panic!("Failed to start epoch"),
101 }
102 }
103
104 println!("\nLinear flow example complete!");
105}Sourcepub fn do_action(&mut self, action: &NetAction) -> NetActionResponse
pub fn do_action(&mut self, action: &NetAction) -> NetActionResponse
Perform an action on the network.
This is the primary way to mutate the network state. All actions produce a response containing either success data and events, or an error.
§Example
use netrun_sim::net::{Net, NetAction, NetActionResponse, NetActionResponseData};
use netrun_sim::graph::{Graph, Node, Port, PortSlotSpec};
use std::collections::HashMap;
let node = Node {
name: "A".to_string(),
in_ports: HashMap::new(),
out_ports: HashMap::new(),
in_salvo_conditions: HashMap::new(),
out_salvo_conditions: HashMap::new(),
};
let graph = Graph::new(vec![node], vec![]);
let mut net = Net::new(graph);
// Create a packet outside the network
let response = net.do_action(&NetAction::CreatePacket(None));
match response {
NetActionResponse::Success(NetActionResponseData::Packet(id), events) => {
println!("Created packet {}", id);
}
_ => panic!("Expected success"),
}Examples found in repository?
examples/diamond_flow.rs (line 39)
24fn main() {
25 // Create a diamond graph
26 let graph = create_diamond_graph();
27 println!("Created diamond graph: A -> B,C -> D");
28 println!("D requires inputs from BOTH B and C\n");
29
30 let mut net = Net::new(graph);
31
32 // Create two packets and place them on edges from A
33 let packet1 = create_packet(&mut net);
34 let packet2 = create_packet(&mut net);
35 println!("Created packets: {} and {}", packet1, packet2);
36
37 // Place packet1 on edge A -> B
38 let edge_a_b = edge_location("A", "out1", "B", "in");
39 net.do_action(&NetAction::TransportPacketToLocation(packet1.clone(), edge_a_b));
40 println!("Placed packet1 on edge A -> B");
41
42 // Place packet2 on edge A -> C
43 let edge_a_c = edge_location("A", "out2", "C", "in");
44 net.do_action(&NetAction::TransportPacketToLocation(packet2.clone(), edge_a_c));
45 println!("Placed packet2 on edge A -> C");
46
47 // Run network - packets move to B and C, triggering epochs
48 net.do_action(&NetAction::RunNetUntilBlocked);
49
50 let startable = net.get_startable_epochs();
51 println!("\nAfter first run: {} startable epochs (B and C)", startable.len());
52
53 // Process B and C, sending outputs to D
54 for epoch_id in startable {
55 let epoch = net.get_epoch(&epoch_id).unwrap();
56 let node_name = epoch.node_name.clone();
57 println!("\nProcessing node {}", node_name);
58
59 // Start the epoch
60 let started = match net.do_action(&NetAction::StartEpoch(epoch_id.clone())) {
61 NetActionResponse::Success(NetActionResponseData::StartedEpoch(e), _) => e,
62 _ => panic!("Failed to start epoch"),
63 };
64
65 // Find and consume the input packet
66 let input_packet = started.in_salvo.packets[0].1.clone();
67 net.do_action(&NetAction::ConsumePacket(input_packet));
68
69 // Create output packet
70 let output = create_packet_in_epoch(&mut net, &started.id);
71
72 // Load into output port and send
73 net.do_action(&NetAction::LoadPacketIntoOutputPort(output, "out".to_string()));
74 net.do_action(&NetAction::SendOutputSalvo(started.id.clone(), "default".to_string()));
75
76 // Finish epoch
77 net.do_action(&NetAction::FinishEpoch(started.id));
78 println!(" Finished {} - sent packet to D", node_name);
79 }
80
81 // Run network - packets move from B->D and C->D edges to D's input ports
82 net.do_action(&NetAction::RunNetUntilBlocked);
83
84 // Check D's input ports
85 let d_in1 = PacketLocation::InputPort("D".to_string(), "in1".to_string());
86 let d_in2 = PacketLocation::InputPort("D".to_string(), "in2".to_string());
87 println!("\nD's input ports:");
88 println!(" in1 (from B): {} packets", net.packet_count_at(&d_in1));
89 println!(" in2 (from C): {} packets", net.packet_count_at(&d_in2));
90
91 // D should now have a startable epoch (both inputs present)
92 let startable_d = net.get_startable_epochs();
93 println!("\nStartable epochs at D: {}", startable_d.len());
94
95 if let Some(d_epoch_id) = startable_d.first() {
96 let d_epoch = net.get_epoch(d_epoch_id).unwrap();
97 println!("D's epoch received {} packets from both branches!", d_epoch.in_salvo.packets.len());
98 }
99
100 println!("\nDiamond flow example complete!");
101}
102
103fn create_diamond_graph() -> Graph {
104 // Node A: source with two outputs
105 let node_a = Node {
106 name: "A".to_string(),
107 in_ports: HashMap::new(),
108 out_ports: [
109 ("out1".to_string(), Port { slots_spec: PortSlotSpec::Infinite }),
110 ("out2".to_string(), Port { slots_spec: PortSlotSpec::Infinite }),
111 ].into(),
112 in_salvo_conditions: HashMap::new(),
113 out_salvo_conditions: HashMap::new(),
114 };
115
116 // Node B: one input, one output
117 let node_b = create_simple_node("B");
118
119 // Node C: one input, one output
120 let node_c = create_simple_node("C");
121
122 // Node D: TWO inputs (requires both), no outputs
123 let node_d = Node {
124 name: "D".to_string(),
125 in_ports: [
126 ("in1".to_string(), Port { slots_spec: PortSlotSpec::Infinite }),
127 ("in2".to_string(), Port { slots_spec: PortSlotSpec::Infinite }),
128 ].into(),
129 out_ports: HashMap::new(),
130 in_salvo_conditions: [(
131 "default".to_string(),
132 SalvoCondition {
133 max_salvos: 1,
134 ports: vec!["in1".to_string(), "in2".to_string()],
135 // Require BOTH inputs to be non-empty
136 term: SalvoConditionTerm::And(vec![
137 SalvoConditionTerm::Port {
138 port_name: "in1".to_string(),
139 state: PortState::NonEmpty,
140 },
141 SalvoConditionTerm::Port {
142 port_name: "in2".to_string(),
143 state: PortState::NonEmpty,
144 },
145 ]),
146 },
147 )].into(),
148 out_salvo_conditions: HashMap::new(),
149 };
150
151 let edges = vec![
152 create_edge("A", "out1", "B", "in"),
153 create_edge("A", "out2", "C", "in"),
154 create_edge("B", "out", "D", "in1"),
155 create_edge("C", "out", "D", "in2"),
156 ];
157
158 let graph = Graph::new(vec![node_a, node_b, node_c, node_d], edges);
159 assert!(graph.validate().is_empty(), "Graph validation failed");
160 graph
161}
162
163fn create_simple_node(name: &str) -> Node {
164 Node {
165 name: name.to_string(),
166 in_ports: [("in".to_string(), Port { slots_spec: PortSlotSpec::Infinite })].into(),
167 out_ports: [("out".to_string(), Port { slots_spec: PortSlotSpec::Infinite })].into(),
168 in_salvo_conditions: [(
169 "default".to_string(),
170 SalvoCondition {
171 max_salvos: 1,
172 ports: vec!["in".to_string()],
173 term: SalvoConditionTerm::Port {
174 port_name: "in".to_string(),
175 state: PortState::NonEmpty,
176 },
177 },
178 )].into(),
179 out_salvo_conditions: [(
180 "default".to_string(),
181 SalvoCondition {
182 max_salvos: 0,
183 ports: vec!["out".to_string()],
184 term: SalvoConditionTerm::Port {
185 port_name: "out".to_string(),
186 state: PortState::NonEmpty,
187 },
188 },
189 )].into(),
190 }
191}
192
193fn create_edge(src_node: &str, src_port: &str, tgt_node: &str, tgt_port: &str) -> Edge {
194 Edge {
195 source: PortRef {
196 node_name: src_node.to_string(),
197 port_type: PortType::Output,
198 port_name: src_port.to_string(),
199 },
200 target: PortRef {
201 node_name: tgt_node.to_string(),
202 port_type: PortType::Input,
203 port_name: tgt_port.to_string(),
204 },
205 }
206}
207
208fn edge_location(src_node: &str, src_port: &str, tgt_node: &str, tgt_port: &str) -> PacketLocation {
209 PacketLocation::Edge(Edge {
210 source: PortRef {
211 node_name: src_node.to_string(),
212 port_type: PortType::Output,
213 port_name: src_port.to_string(),
214 },
215 target: PortRef {
216 node_name: tgt_node.to_string(),
217 port_type: PortType::Input,
218 port_name: tgt_port.to_string(),
219 },
220 })
221}
222
223fn create_packet(net: &mut Net) -> ulid::Ulid {
224 match net.do_action(&NetAction::CreatePacket(None)) {
225 NetActionResponse::Success(NetActionResponseData::Packet(id), _) => id,
226 _ => panic!("Failed to create packet"),
227 }
228}
229
230fn create_packet_in_epoch(net: &mut Net, epoch_id: &ulid::Ulid) -> ulid::Ulid {
231 match net.do_action(&NetAction::CreatePacket(Some(epoch_id.clone()))) {
232 NetActionResponse::Success(NetActionResponseData::Packet(id), _) => id,
233 _ => panic!("Failed to create packet in epoch"),
234 }
235}More examples
examples/linear_flow.rs (line 28)
19fn main() {
20 // Create a linear graph: A -> B -> C
21 let graph = create_linear_graph();
22 println!("Created graph with {} nodes", graph.nodes().len());
23
24 // Create a network from the graph
25 let mut net = Net::new(graph);
26
27 // Create a packet outside the network
28 let packet_id = match net.do_action(&NetAction::CreatePacket(None)) {
29 NetActionResponse::Success(NetActionResponseData::Packet(id), _) => {
30 println!("Created packet: {}", id);
31 id
32 }
33 _ => panic!("Failed to create packet"),
34 };
35
36 // Transport packet to the edge A -> B
37 let edge_a_b = PacketLocation::Edge(Edge {
38 source: PortRef {
39 node_name: "A".to_string(),
40 port_type: PortType::Output,
41 port_name: "out".to_string(),
42 },
43 target: PortRef {
44 node_name: "B".to_string(),
45 port_type: PortType::Input,
46 port_name: "in".to_string(),
47 },
48 });
49 net.do_action(&NetAction::TransportPacketToLocation(packet_id.clone(), edge_a_b));
50 println!("Placed packet on edge A -> B");
51
52 // Run the network - packet moves to B's input port and triggers an epoch
53 net.do_action(&NetAction::RunNetUntilBlocked);
54 println!("Ran network until blocked");
55
56 // Check for startable epochs
57 let startable = net.get_startable_epochs();
58 println!("Startable epochs: {}", startable.len());
59
60 if let Some(epoch_id) = startable.first() {
61 // Start the epoch
62 match net.do_action(&NetAction::StartEpoch(epoch_id.clone())) {
63 NetActionResponse::Success(NetActionResponseData::StartedEpoch(epoch), _) => {
64 println!("Started epoch {} on node {}", epoch.id, epoch.node_name);
65
66 // In a real scenario, external code would process the packet here
67 // For this example, we'll just consume it and create an output
68
69 // Consume the input packet
70 net.do_action(&NetAction::ConsumePacket(packet_id));
71 println!("Consumed input packet");
72
73 // Create an output packet
74 let output_packet = match net.do_action(&NetAction::CreatePacket(Some(epoch.id.clone()))) {
75 NetActionResponse::Success(NetActionResponseData::Packet(id), _) => id,
76 _ => panic!("Failed to create output packet"),
77 };
78 println!("Created output packet: {}", output_packet);
79
80 // Load it into the output port
81 net.do_action(&NetAction::LoadPacketIntoOutputPort(output_packet.clone(), "out".to_string()));
82 println!("Loaded packet into output port");
83
84 // Send the output salvo
85 net.do_action(&NetAction::SendOutputSalvo(epoch.id.clone(), "default".to_string()));
86 println!("Sent output salvo - packet is now on edge B -> C");
87
88 // Finish the epoch
89 net.do_action(&NetAction::FinishEpoch(epoch.id));
90 println!("Finished epoch");
91
92 // Run the network again - packet moves to C
93 net.do_action(&NetAction::RunNetUntilBlocked);
94 println!("Ran network until blocked again");
95
96 // Check for new startable epochs at C
97 let startable_c = net.get_startable_epochs();
98 println!("New startable epochs (should be at C): {}", startable_c.len());
99 }
100 _ => panic!("Failed to start epoch"),
101 }
102 }
103
104 println!("\nLinear flow example complete!");
105}Sourcepub fn packet_count_at(&self, location: &PacketLocation) -> usize
pub fn packet_count_at(&self, location: &PacketLocation) -> usize
Get the number of packets at a given location.
Examples found in repository?
examples/diamond_flow.rs (line 88)
24fn main() {
25 // Create a diamond graph
26 let graph = create_diamond_graph();
27 println!("Created diamond graph: A -> B,C -> D");
28 println!("D requires inputs from BOTH B and C\n");
29
30 let mut net = Net::new(graph);
31
32 // Create two packets and place them on edges from A
33 let packet1 = create_packet(&mut net);
34 let packet2 = create_packet(&mut net);
35 println!("Created packets: {} and {}", packet1, packet2);
36
37 // Place packet1 on edge A -> B
38 let edge_a_b = edge_location("A", "out1", "B", "in");
39 net.do_action(&NetAction::TransportPacketToLocation(packet1.clone(), edge_a_b));
40 println!("Placed packet1 on edge A -> B");
41
42 // Place packet2 on edge A -> C
43 let edge_a_c = edge_location("A", "out2", "C", "in");
44 net.do_action(&NetAction::TransportPacketToLocation(packet2.clone(), edge_a_c));
45 println!("Placed packet2 on edge A -> C");
46
47 // Run network - packets move to B and C, triggering epochs
48 net.do_action(&NetAction::RunNetUntilBlocked);
49
50 let startable = net.get_startable_epochs();
51 println!("\nAfter first run: {} startable epochs (B and C)", startable.len());
52
53 // Process B and C, sending outputs to D
54 for epoch_id in startable {
55 let epoch = net.get_epoch(&epoch_id).unwrap();
56 let node_name = epoch.node_name.clone();
57 println!("\nProcessing node {}", node_name);
58
59 // Start the epoch
60 let started = match net.do_action(&NetAction::StartEpoch(epoch_id.clone())) {
61 NetActionResponse::Success(NetActionResponseData::StartedEpoch(e), _) => e,
62 _ => panic!("Failed to start epoch"),
63 };
64
65 // Find and consume the input packet
66 let input_packet = started.in_salvo.packets[0].1.clone();
67 net.do_action(&NetAction::ConsumePacket(input_packet));
68
69 // Create output packet
70 let output = create_packet_in_epoch(&mut net, &started.id);
71
72 // Load into output port and send
73 net.do_action(&NetAction::LoadPacketIntoOutputPort(output, "out".to_string()));
74 net.do_action(&NetAction::SendOutputSalvo(started.id.clone(), "default".to_string()));
75
76 // Finish epoch
77 net.do_action(&NetAction::FinishEpoch(started.id));
78 println!(" Finished {} - sent packet to D", node_name);
79 }
80
81 // Run network - packets move from B->D and C->D edges to D's input ports
82 net.do_action(&NetAction::RunNetUntilBlocked);
83
84 // Check D's input ports
85 let d_in1 = PacketLocation::InputPort("D".to_string(), "in1".to_string());
86 let d_in2 = PacketLocation::InputPort("D".to_string(), "in2".to_string());
87 println!("\nD's input ports:");
88 println!(" in1 (from B): {} packets", net.packet_count_at(&d_in1));
89 println!(" in2 (from C): {} packets", net.packet_count_at(&d_in2));
90
91 // D should now have a startable epoch (both inputs present)
92 let startable_d = net.get_startable_epochs();
93 println!("\nStartable epochs at D: {}", startable_d.len());
94
95 if let Some(d_epoch_id) = startable_d.first() {
96 let d_epoch = net.get_epoch(d_epoch_id).unwrap();
97 println!("D's epoch received {} packets from both branches!", d_epoch.in_salvo.packets.len());
98 }
99
100 println!("\nDiamond flow example complete!");
101}Sourcepub fn get_packets_at_location(
&self,
location: &PacketLocation,
) -> Vec<PacketID> ⓘ
pub fn get_packets_at_location( &self, location: &PacketLocation, ) -> Vec<PacketID> ⓘ
Get all packets at a given location.
Sourcepub fn get_epoch(&self, epoch_id: &EpochID) -> Option<&Epoch>
pub fn get_epoch(&self, epoch_id: &EpochID) -> Option<&Epoch>
Get an epoch by ID.
Examples found in repository?
examples/diamond_flow.rs (line 55)
24fn main() {
25 // Create a diamond graph
26 let graph = create_diamond_graph();
27 println!("Created diamond graph: A -> B,C -> D");
28 println!("D requires inputs from BOTH B and C\n");
29
30 let mut net = Net::new(graph);
31
32 // Create two packets and place them on edges from A
33 let packet1 = create_packet(&mut net);
34 let packet2 = create_packet(&mut net);
35 println!("Created packets: {} and {}", packet1, packet2);
36
37 // Place packet1 on edge A -> B
38 let edge_a_b = edge_location("A", "out1", "B", "in");
39 net.do_action(&NetAction::TransportPacketToLocation(packet1.clone(), edge_a_b));
40 println!("Placed packet1 on edge A -> B");
41
42 // Place packet2 on edge A -> C
43 let edge_a_c = edge_location("A", "out2", "C", "in");
44 net.do_action(&NetAction::TransportPacketToLocation(packet2.clone(), edge_a_c));
45 println!("Placed packet2 on edge A -> C");
46
47 // Run network - packets move to B and C, triggering epochs
48 net.do_action(&NetAction::RunNetUntilBlocked);
49
50 let startable = net.get_startable_epochs();
51 println!("\nAfter first run: {} startable epochs (B and C)", startable.len());
52
53 // Process B and C, sending outputs to D
54 for epoch_id in startable {
55 let epoch = net.get_epoch(&epoch_id).unwrap();
56 let node_name = epoch.node_name.clone();
57 println!("\nProcessing node {}", node_name);
58
59 // Start the epoch
60 let started = match net.do_action(&NetAction::StartEpoch(epoch_id.clone())) {
61 NetActionResponse::Success(NetActionResponseData::StartedEpoch(e), _) => e,
62 _ => panic!("Failed to start epoch"),
63 };
64
65 // Find and consume the input packet
66 let input_packet = started.in_salvo.packets[0].1.clone();
67 net.do_action(&NetAction::ConsumePacket(input_packet));
68
69 // Create output packet
70 let output = create_packet_in_epoch(&mut net, &started.id);
71
72 // Load into output port and send
73 net.do_action(&NetAction::LoadPacketIntoOutputPort(output, "out".to_string()));
74 net.do_action(&NetAction::SendOutputSalvo(started.id.clone(), "default".to_string()));
75
76 // Finish epoch
77 net.do_action(&NetAction::FinishEpoch(started.id));
78 println!(" Finished {} - sent packet to D", node_name);
79 }
80
81 // Run network - packets move from B->D and C->D edges to D's input ports
82 net.do_action(&NetAction::RunNetUntilBlocked);
83
84 // Check D's input ports
85 let d_in1 = PacketLocation::InputPort("D".to_string(), "in1".to_string());
86 let d_in2 = PacketLocation::InputPort("D".to_string(), "in2".to_string());
87 println!("\nD's input ports:");
88 println!(" in1 (from B): {} packets", net.packet_count_at(&d_in1));
89 println!(" in2 (from C): {} packets", net.packet_count_at(&d_in2));
90
91 // D should now have a startable epoch (both inputs present)
92 let startable_d = net.get_startable_epochs();
93 println!("\nStartable epochs at D: {}", startable_d.len());
94
95 if let Some(d_epoch_id) = startable_d.first() {
96 let d_epoch = net.get_epoch(d_epoch_id).unwrap();
97 println!("D's epoch received {} packets from both branches!", d_epoch.in_salvo.packets.len());
98 }
99
100 println!("\nDiamond flow example complete!");
101}Sourcepub fn get_startable_epochs(&self) -> Vec<EpochID> ⓘ
pub fn get_startable_epochs(&self) -> Vec<EpochID> ⓘ
Get all startable epoch IDs.
Examples found in repository?
examples/diamond_flow.rs (line 50)
24fn main() {
25 // Create a diamond graph
26 let graph = create_diamond_graph();
27 println!("Created diamond graph: A -> B,C -> D");
28 println!("D requires inputs from BOTH B and C\n");
29
30 let mut net = Net::new(graph);
31
32 // Create two packets and place them on edges from A
33 let packet1 = create_packet(&mut net);
34 let packet2 = create_packet(&mut net);
35 println!("Created packets: {} and {}", packet1, packet2);
36
37 // Place packet1 on edge A -> B
38 let edge_a_b = edge_location("A", "out1", "B", "in");
39 net.do_action(&NetAction::TransportPacketToLocation(packet1.clone(), edge_a_b));
40 println!("Placed packet1 on edge A -> B");
41
42 // Place packet2 on edge A -> C
43 let edge_a_c = edge_location("A", "out2", "C", "in");
44 net.do_action(&NetAction::TransportPacketToLocation(packet2.clone(), edge_a_c));
45 println!("Placed packet2 on edge A -> C");
46
47 // Run network - packets move to B and C, triggering epochs
48 net.do_action(&NetAction::RunNetUntilBlocked);
49
50 let startable = net.get_startable_epochs();
51 println!("\nAfter first run: {} startable epochs (B and C)", startable.len());
52
53 // Process B and C, sending outputs to D
54 for epoch_id in startable {
55 let epoch = net.get_epoch(&epoch_id).unwrap();
56 let node_name = epoch.node_name.clone();
57 println!("\nProcessing node {}", node_name);
58
59 // Start the epoch
60 let started = match net.do_action(&NetAction::StartEpoch(epoch_id.clone())) {
61 NetActionResponse::Success(NetActionResponseData::StartedEpoch(e), _) => e,
62 _ => panic!("Failed to start epoch"),
63 };
64
65 // Find and consume the input packet
66 let input_packet = started.in_salvo.packets[0].1.clone();
67 net.do_action(&NetAction::ConsumePacket(input_packet));
68
69 // Create output packet
70 let output = create_packet_in_epoch(&mut net, &started.id);
71
72 // Load into output port and send
73 net.do_action(&NetAction::LoadPacketIntoOutputPort(output, "out".to_string()));
74 net.do_action(&NetAction::SendOutputSalvo(started.id.clone(), "default".to_string()));
75
76 // Finish epoch
77 net.do_action(&NetAction::FinishEpoch(started.id));
78 println!(" Finished {} - sent packet to D", node_name);
79 }
80
81 // Run network - packets move from B->D and C->D edges to D's input ports
82 net.do_action(&NetAction::RunNetUntilBlocked);
83
84 // Check D's input ports
85 let d_in1 = PacketLocation::InputPort("D".to_string(), "in1".to_string());
86 let d_in2 = PacketLocation::InputPort("D".to_string(), "in2".to_string());
87 println!("\nD's input ports:");
88 println!(" in1 (from B): {} packets", net.packet_count_at(&d_in1));
89 println!(" in2 (from C): {} packets", net.packet_count_at(&d_in2));
90
91 // D should now have a startable epoch (both inputs present)
92 let startable_d = net.get_startable_epochs();
93 println!("\nStartable epochs at D: {}", startable_d.len());
94
95 if let Some(d_epoch_id) = startable_d.first() {
96 let d_epoch = net.get_epoch(d_epoch_id).unwrap();
97 println!("D's epoch received {} packets from both branches!", d_epoch.in_salvo.packets.len());
98 }
99
100 println!("\nDiamond flow example complete!");
101}More examples
examples/linear_flow.rs (line 57)
19fn main() {
20 // Create a linear graph: A -> B -> C
21 let graph = create_linear_graph();
22 println!("Created graph with {} nodes", graph.nodes().len());
23
24 // Create a network from the graph
25 let mut net = Net::new(graph);
26
27 // Create a packet outside the network
28 let packet_id = match net.do_action(&NetAction::CreatePacket(None)) {
29 NetActionResponse::Success(NetActionResponseData::Packet(id), _) => {
30 println!("Created packet: {}", id);
31 id
32 }
33 _ => panic!("Failed to create packet"),
34 };
35
36 // Transport packet to the edge A -> B
37 let edge_a_b = PacketLocation::Edge(Edge {
38 source: PortRef {
39 node_name: "A".to_string(),
40 port_type: PortType::Output,
41 port_name: "out".to_string(),
42 },
43 target: PortRef {
44 node_name: "B".to_string(),
45 port_type: PortType::Input,
46 port_name: "in".to_string(),
47 },
48 });
49 net.do_action(&NetAction::TransportPacketToLocation(packet_id.clone(), edge_a_b));
50 println!("Placed packet on edge A -> B");
51
52 // Run the network - packet moves to B's input port and triggers an epoch
53 net.do_action(&NetAction::RunNetUntilBlocked);
54 println!("Ran network until blocked");
55
56 // Check for startable epochs
57 let startable = net.get_startable_epochs();
58 println!("Startable epochs: {}", startable.len());
59
60 if let Some(epoch_id) = startable.first() {
61 // Start the epoch
62 match net.do_action(&NetAction::StartEpoch(epoch_id.clone())) {
63 NetActionResponse::Success(NetActionResponseData::StartedEpoch(epoch), _) => {
64 println!("Started epoch {} on node {}", epoch.id, epoch.node_name);
65
66 // In a real scenario, external code would process the packet here
67 // For this example, we'll just consume it and create an output
68
69 // Consume the input packet
70 net.do_action(&NetAction::ConsumePacket(packet_id));
71 println!("Consumed input packet");
72
73 // Create an output packet
74 let output_packet = match net.do_action(&NetAction::CreatePacket(Some(epoch.id.clone()))) {
75 NetActionResponse::Success(NetActionResponseData::Packet(id), _) => id,
76 _ => panic!("Failed to create output packet"),
77 };
78 println!("Created output packet: {}", output_packet);
79
80 // Load it into the output port
81 net.do_action(&NetAction::LoadPacketIntoOutputPort(output_packet.clone(), "out".to_string()));
82 println!("Loaded packet into output port");
83
84 // Send the output salvo
85 net.do_action(&NetAction::SendOutputSalvo(epoch.id.clone(), "default".to_string()));
86 println!("Sent output salvo - packet is now on edge B -> C");
87
88 // Finish the epoch
89 net.do_action(&NetAction::FinishEpoch(epoch.id));
90 println!("Finished epoch");
91
92 // Run the network again - packet moves to C
93 net.do_action(&NetAction::RunNetUntilBlocked);
94 println!("Ran network until blocked again");
95
96 // Check for new startable epochs at C
97 let startable_c = net.get_startable_epochs();
98 println!("New startable epochs (should be at C): {}", startable_c.len());
99 }
100 _ => panic!("Failed to start epoch"),
101 }
102 }
103
104 println!("\nLinear flow example complete!");
105}Sourcepub fn get_packet(&self, packet_id: &PacketID) -> Option<&Packet>
pub fn get_packet(&self, packet_id: &PacketID) -> Option<&Packet>
Get a packet by ID.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Net
impl RefUnwindSafe for Net
impl Send for Net
impl Sync for Net
impl Unpin for Net
impl UnwindSafe for Net
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more