use aetherflow::{pinning, Actor, ActorRef, System};
use std::sync::mpsc;
#[derive(Debug)]
struct Order {
symbol: u8,
id: u64,
qty: u32,
}
struct Engine {
symbol: u8,
filled: u64,
out: mpsc::Sender<String>,
}
impl Actor for Engine {
type Message = Order;
fn on_start(&mut self) {
self.out
.send(format!("engine[sym={}] started", self.symbol))
.unwrap();
}
fn handle(&mut self, o: Order) {
self.filled += o.qty as u64;
self.out
.send(format!(
" sym={} order#{} qty={} filled_total={}",
o.symbol, o.id, o.qty, self.filled
))
.unwrap();
}
fn on_stop(&mut self) {
self.out
.send(format!("engine[sym={}] stopped total={}", self.symbol, self.filled))
.unwrap();
}
}
struct Gateway {
engines: Vec<ActorRef<Engine>>,
}
impl Actor for Gateway {
type Message = Order;
fn handle(&mut self, o: Order) {
let idx = (o.symbol as usize) % self.engines.len();
let _ = self.engines[idx].try_send(o); }
}
fn main() {
println!("available logical cores: {:?}", pinning::available_cores());
const SYMBOLS: u8 = 3;
let sys = System::with_cores((SYMBOLS as usize) + 1); let (out, log) = mpsc::channel();
let engines: Vec<ActorRef<Engine>> = (0..SYMBOLS)
.map(|s| {
sys.spawn_on(
(s as usize) + 1,
Engine {
symbol: s,
filled: 0,
out: out.clone(),
},
)
})
.collect();
let gateway = sys.spawn_on(0, Gateway { engines: engines.clone() });
for id in 1..=12u64 {
let order = Order {
symbol: (id % SYMBOLS as u64) as u8,
id,
qty: (id * 10) as u32,
};
gateway.send_blocking(order).unwrap();
}
drop(gateway);
drop(engines);
drop(out);
sys.shutdown();
let mut lines: Vec<String> = log.iter().collect();
lines.sort(); for l in lines {
println!("{l}");
}
}