Message Passing
Mailbox Drain
Process Messages in Order
A mailbox can be modeled as a queue of messages drained by one receiver in first-in, first-out order.
Program
Play the program to choose the second message and drain the mailbox into one summary.
mailbox_drain.rs
Replay: real traced execution (multi-file project)
use std::collections::VecDeque;
fn main() {
let second = "ack";
let mut mailbox = VecDeque::new();
mailbox.push_back("open");
mailbox.push_back(second);
let summary = drain(&mut mailbox);
println!("{summary}");
}
fn drain(mailbox: &mut VecDeque<&str>) -> String {
let mut seen = Vec::new();
while let Some(message) = mailbox.pop_front() {
seen.push(message);
}
seen.join(",")
}
use std::collections::VecDeque;
fn main() {
let second = "retry";
let mut mailbox = VecDeque::new();
mailbox.push_back("open");
mailbox.push_back(second);
let summary = drain(&mut mailbox);
println!("{summary}");
}
fn drain(mailbox: &mut VecDeque<&str>) -> String {
let mut seen = Vec::new();
while let Some(message) = mailbox.pop_front() {
seen.push(message);
}
seen.join(",")
}
use std::collections::VecDeque;
fn main() {
let second = "done";
let mut mailbox = VecDeque::new();
mailbox.push_back("open");
mailbox.push_back(second);
let summary = drain(&mut mailbox);
println!("{summary}");
}
fn drain(mailbox: &mut VecDeque<&str>) -> String {
let mut seen = Vec::new();
while let Some(message) = mailbox.pop_front() {
seen.push(message);
}
seen.join(",")
}
second ← "ack", mailbox ← []
3fn main() {4 let secon→ "ack"d = "ack"; //@second="ack", "retry", "done"5 let mut mailbo→ []x = VecDeque::new();6 mailbox.push_back("open");7 mailbox.push_back(second);8 let summary = drain(&mut mailbo["open", "ack"]x);9 println!("{summary}");seen ← []
12fn drain(mailbox: &mut VecDeque<&str>) -> String {13 let mut see→ []n = Vec::new();14 while let Some(message) = mailbox.pop_front() {seen.join(",")
16 }17 seen.join(",")18}mailbox ← [], summary ← "open,ack"
7 mailbox.push_back(second);8 let summar→ "open,ack"y = drain(&mut mailbo→ []x);9 println!("{summary}");10}outputopen,ack
second ← "retry", mailbox ← []
3fn main() {4 let secon→ "retry"d = "retry";5 let mut mailbo→ []x = VecDeque::new();6 mailbox.push_back("open");7 mailbox.push_back(second);8 let summary = drain(&mut mailbo["open", "retry"]x);9 println!("{summary}");seen ← []
12fn drain(mailbox: &mut VecDeque<&str>) -> String {13 let mut see→ []n = Vec::new();14 while let Some(message) = mailbox.pop_front() {seen.join(",")
16 }17 seen.join(",")18}mailbox ← [], summary ← "open,retry"
7 mailbox.push_back(second);8 let summar→ "open,retry"y = drain(&mut mailbo→ []x);9 println!("{summary}");10}outputopen,retry
second ← "done", mailbox ← []
3fn main() {4 let secon→ "done"d = "done";5 let mut mailbo→ []x = VecDeque::new();6 mailbox.push_back("open");7 mailbox.push_back(second);8 let summary = drain(&mut mailbo["open", "done"]x);9 println!("{summary}");seen ← []
12fn drain(mailbox: &mut VecDeque<&str>) -> String {13 let mut see→ []n = Vec::new();14 while let Some(message) = mailbox.pop_front() {seen.join(",")
16 }17 seen.join(",")18}mailbox ← [], summary ← "open,done"
7 mailbox.push_back(second);8 let summar→ "open,done"y = drain(&mut mailbo→ []x);9 println!("{summary}");10}outputopen,done
mailbox
`VecDeque` models a queue that can push at the back and pop from the front.
drain
`while let Some(...)` keeps receiving until the mailbox is empty.
ordering
`pop_front` preserves the order in which messages were queued.