Simulating a Message Passing Network in Rust
Write a Rust program to simulate a message passing network, where each node communicates with its neighboring nodes through channels. Implement message routing and forwarding between nodes.
Sample Solution:
Rust Code:
use std::sync::{Arc, Mutex};
use std::sync::mpsc;
use std::thread;
const NUM_NODES: usize = 5;
fn main() {
// Create channels for communication between nodes
let mut channels = Vec::new();
for _ in 0..NUM_NODES {
let (sender, receiver) = mpsc::channel();
channels.push(Arc::new(Mutex::new((sender, receiver))));
}
// Spawn threads for each node
let mut handles = Vec::new();
for i in 0..NUM_NODES {
let _next_node = (i + 1) % NUM_NODES;
let prev_node = if i == 0 { NUM_NODES - 1 } else { i - 1 };
let sender = Arc::clone(&channels[i]);
let receiver = Arc::clone(&channels[prev_node]);
let handle = thread::spawn(move || {
node(i, sender, receiver);
});
handles.push(handle);
}
// Send a message from the first node
let message = "Hello from Node 0!";
channels[0].lock().unwrap().0.send(message.to_string()).unwrap();
// Wait for all threads to finish
for handle in handles {
handle.join().unwrap();
}
}
fn node(id: usize, sender: Arc<Mutex<(mpsc::Sender<String>, mpsc::Receiver<String>)>>, receiver: Arc<Mutex<(mpsc::Sender<String>, mpsc::Receiver<String>)>>) {
loop {
// Receive message from previous node
let received_msg = receiver.lock().unwrap().1.recv().unwrap();
println!("Node {}: Received message: {}", id, received_msg);
// Forward message to next node
let forwarded_msg = format!("Forwarded from Node {} to Node {}", id, (id + 1) % NUM_NODES);
sender.lock().unwrap().0.send(forwarded_msg.clone()).unwrap();
println!("Node {}: Forwarded message: {}", id, forwarded_msg);
}
}
Output:
Node 1: Received message: Hello from Node 0! Node 1: Forwarded message: Forwarded from Node 1 to Node 2 Node 2: Received message: Forwarded from Node 1 to Node 2
Explanation:
In the exercise above,
- Import necessary modules for synchronization ("Arc", "Mutex"), inter-thread communication ('mpsc'), and multi-threading ('thread').
- Constants: It defines 'NUM_NODES' as the number of nodes in the network.
- Main Function:
- Channel Creation: It creates a vector 'channels' to hold channels for communication between nodes. Each channel consists of a sender and a receiver.
- Node Threads: It spawns threads for each node in the network. Each thread represents a node and executes the "node()" function. The sender and receiver for each node are obtained from the 'channels' vector, ensuring that each node communicates with its adjacent nodes.
- Message Sending: It sends a message from the first node (Node 0) to kickstart the communication process.
- Thread Joining: It waits for all node threads to finish executing before the program exits.
- Node Function:
- Message Receiving: It continuously receives messages from the previous node (as determined by the index of the 'channels' vector).
- Message Forwarding: It forwards the received message to the next node in the network. The message includes information about the current node and the next node it's being forwarded to.
Rust Code Editor:
Previous: Rust Producer-Consumer Pattern with Channels.
Next: Implementing Synchronous Channels in Rust.
What is the difficulty level of this exercise?
Test your Programming skills with w3resource's quiz.
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics