Q1: considering the code below: Is there something wrong with this approach where the protocol object is shared between peers, and each peer runs the object's run method and keep it running?
Q2: Regarding the protocol list type, it's of type Arc, and the protocol inside the list is also of type Arc. Will this cause any issues with the protocols handled by the Network and Peer objects?
use async_std::sync::{Arc, Mutex};
use async_trait::async_trait;
#[async_trait]
trait Protocol: Send + Sync {
async fn run(self: Arc<Self>, peer: Arc<Peer>);
}
struct TestProtocol {}
#[async_trait]
impl Protocol for TestProtocol {
async fn run(self: Arc<Self>, peer: Arc<Peer>) {
println!("run test protocol for peer {}", peer.name);
loop {
// code here
}
}
}
struct Network {
protocols: Arc<Mutex<Vec<Arc<dyn Protocol>>>>,
}
struct Peer {
protocols: Arc<Mutex<Vec<Arc<dyn Protocol>>>>,
name: String,
}
impl Peer {
fn new(name: String, protocols: Arc<Mutex<Vec<Arc<dyn Protocol>>>>) -> Arc<Self> {
Arc::new(Self { protocols, name })
}
async fn start(self: Arc<Self>) {
for proto in self.clone().protocols.lock().await.iter() {
async_std::task::spawn(proto.clone().run(self.clone()));
}
}
}
#[async_std::main]
async fn main() {
let network = Network {
protocols: Arc::new(Mutex::new(vec![Arc::new(TestProtocol {})])),
};
let peer1 = Peer::new("peer1".into(), network.protocols.clone());
peer1.start().await;
let peer2 = Peer::new("peer2".into(), network.protocols);
peer2.start().await;
async_std::task::sleep(std::time::Duration::from_secs(600)).await;
}
The code is running successfully, but I'm not sure about the design.
Network
doesn't need it around its vec. Do you have anything more concrete that you want this to do? Is this for a simulation? A microservice framework? Will your protocols be stateful? Do the implementations need to know that Peers and Protocols are inArc
s? \$\endgroup\$