main.rs (2945B)
1 use std::sync::Arc; 2 3 use actor_model::{ 4 basic_actor::{Message, RespMessage, basic_actor, resp_actor}, 5 mutex_replacement::actor_replacement, 6 }; 7 use tokio::sync::{Mutex, mpsc::channel, oneshot}; 8 9 #[tokio::main] 10 async fn main() { 11 // 1. Basic actor without responder 12 // let (tx, rx) = channel::<Message>(100); 13 14 // let _actor_handle = tokio::spawn(basic_actor(rx)); 15 16 // for i in 0..10 { 17 // let msg = Message { value: i }; 18 // tx.send(msg).await.unwrap(); 19 // } 20 21 // 2. Basic actor with responder 22 // if we want to send a message to our responding actor, we need to 23 // construct a onshot channel. 24 // let (tx, rx) = channel::<RespMessage>(100); 25 26 // let _resp_actor_handle = tokio::spawn(async { 27 // resp_actor(rx).await; 28 // }); 29 30 // for i in 0..10 { 31 // // We use a oneshot channel because we need the response to be 32 // // sent only once and then close; after that the client code 33 // // can go about doing other things. 34 // let (resp_tx, resp_rx) = oneshot::channel::<i64>(); 35 36 // let msg = RespMessage { 37 // value: i, 38 // responder: resp_tx, 39 // }; 40 41 // tx.send(msg).await.unwrap(); 42 // println!("Response: {}", resp_rx.await.unwrap()); 43 // } 44 45 // 3.1 Actor replacement using mutex: Elapsed: 602.618µs 46 // let state = Arc::new(Mutex::new(0)); 47 // let mut handles = Vec::new(); 48 49 // let now = tokio::time::Instant::now(); 50 51 // for i in 0..100 { 52 // let state_ref = state.clone(); 53 // let future = async move { 54 // let handle = tokio::spawn(async move { actor_replacement(state_ref, i).await }); 55 56 // let _ = handle.await.unwrap(); 57 // }; 58 // handles.push(tokio::spawn(future)); 59 // } 60 // for handle in handles { 61 // let _ = handle.await.unwrap(); 62 // } 63 // println!("Elapsed: {:?}", now.elapsed()); 64 65 // 3.2 Actor approach: Elapsed: 313.017µs 66 // 67 // Generally, passing messages through channels can scale better than 68 // mutexes in concurrent environments, because the senders do not 69 // have to wait for other tasks to finish what they are doing. 70 let (tx, rx) = channel::<RespMessage>(100); 71 let _resp_actor_handle = tokio::spawn(async { 72 resp_actor(rx).await; 73 }); 74 75 let mut handles = Vec::new(); 76 77 let now = tokio::time::Instant::now(); 78 for i in 0..100 { 79 let tx_ref = tx.clone(); 80 81 let future = async move { 82 let (resp_tx, resp_rx) = oneshot::channel::<i64>(); 83 let msg = RespMessage { 84 value: i, 85 responder: resp_tx, 86 }; 87 tx_ref.send(msg).await.unwrap(); 88 let _ = resp_rx.await.unwrap(); 89 }; 90 handles.push(tokio::spawn(future)); 91 } 92 for handle in handles { 93 handle.await.unwrap(); 94 } 95 println!("Elapsed: {:?}", now.elapsed()); 96 }