From 859c89b6fd6b9b69bb9c570a50c3cd9c00398402 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 17 May 2018 18:00:46 -0600 Subject: [PATCH] pattern 3 --- Chapter08/pattern3.rs | 85 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 16 deletions(-) diff --git a/Chapter08/pattern3.rs b/Chapter08/pattern3.rs index 13acac3..f7a144e 100644 --- a/Chapter08/pattern3.rs +++ b/Chapter08/pattern3.rs @@ -3,35 +3,64 @@ use std::sync::mpsc::{channel,Sender,Receiver}; use std::time; extern crate rand; -fn new_ping() -> (Sender, Receiver) { +enum Address { + Ping, + Pong +} +enum Message { + PingPlus(u64), + PongPlus(u64), +} + +fn new_ping() -> (Sender, Receiver<(Address,Message)>) { let (pinginsend,pinginrecv) = channel(); let (pingoutsend,pingoutrecv) = channel(); let mut ping = 1; thread::spawn(move || { let t = time::Duration::from_millis(1000); loop { - let n = pinginrecv.recv().unwrap(); - ping += n; + let msg = pinginrecv.recv().unwrap(); + match msg { + Message::PingPlus(n) => { ping += n; }, + _ => panic!("Unexpected message") + } println!("ping {}", ping); thread::sleep(t); - pingoutsend.send(ping).unwrap(); + pingoutsend.send(( + Address::Pong, + Message::PongPlus(ping) + )).unwrap(); + pingoutsend.send(( + Address::Pong, + Message::PongPlus(ping) + )).unwrap(); } }); (pinginsend, pingoutrecv) } -fn new_pong() -> (Sender, Receiver) { +fn new_pong() -> (Sender, Receiver<(Address,Message)>) { let (ponginsend,ponginrecv) = channel(); let (pongoutsend,pongoutrecv) = channel(); - let mut pong = 2; + let mut pong = 1; thread::spawn(move || { let t = time::Duration::from_millis(1000); loop { - let n = ponginrecv.recv().unwrap(); - pong += n; + let msg = ponginrecv.recv().unwrap(); + match msg { + Message::PongPlus(n) => { pong += n; }, + _ => panic!("Unexpected message") + } println!("pong {}", pong); thread::sleep(t); - pongoutsend.send(pong).unwrap(); + pongoutsend.send(( + Address::Ping, + Message::PingPlus(pong) + )).unwrap(); + pongoutsend.send(( + Address::Ping, + Message::PingPlus(pong) + )).unwrap(); } }); (ponginsend, pongoutrecv) @@ -40,15 +69,39 @@ fn new_pong() -> (Sender, Receiver) { fn main() { let pings = vec![new_ping(), new_ping(), new_ping()]; let pongs = vec![new_pong(), new_pong(), new_pong()]; + + //Start the action + pings[0].0.send(Message::PingPlus(1)).unwrap(); + + //This thread will be the router + let t = time::Duration::from_millis(10); loop { - let mut d = 3; + let mut mail = Vec::new(); - let (ref pingin,ref pingout) = pings[(rand::random::() % 3) as usize]; - pingin.send(d).unwrap(); - d = pingout.recv().unwrap(); + for (_,r) in pings.iter() { + for (addr,msg) in r.try_iter() { + mail.push((addr,msg)); + } + } + for (_,r) in pongs.iter() { + for (addr,msg) in r.try_iter() { + mail.push((addr,msg)); + } + } + + for (addr,msg) in mail.into_iter() { + match addr { + Address::Ping => { + let (ref s,_) = pings[(rand::random::() as usize) % pings.len()]; + s.send(msg).unwrap(); + }, + Address::Pong => { + let (ref s,_) = pongs[(rand::random::() as usize) % pongs.len()]; + s.send(msg).unwrap(); + } + } + } - let (ref pongin,ref pongout) = pongs[(rand::random::() % 3) as usize]; - pongin.send(d).unwrap(); - pongout.recv().unwrap(); + thread::sleep(t); } }