In single threaded contexts, the Router now is treated as yet another actor on the queue. In multithreaded contexts, it gets its own dedicated thread.
68 lines
1.4 KiB
Rust
68 lines
1.4 KiB
Rust
use swactor::{
|
|
actor::{ActorAddress, ActorInterface},
|
|
runtime::{Inbox, Runtime, RuntimeFlavor},
|
|
};
|
|
|
|
#[derive(Debug, Default, Clone)]
|
|
pub struct RingMessage {
|
|
count: usize,
|
|
}
|
|
|
|
impl RingMessage {
|
|
pub fn next(self) -> Self {
|
|
Self {
|
|
count: self.count + 1,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Default)]
|
|
struct RingActor {
|
|
next: ActorAddress,
|
|
}
|
|
|
|
impl RingActor {
|
|
pub fn new(next: ActorAddress) -> Self {
|
|
Self { next }
|
|
}
|
|
}
|
|
|
|
impl ActorInterface for RingActor {
|
|
type Incoming = RingMessage;
|
|
type Response = ();
|
|
fn handle(&mut self, ctx: &Runtime, msg: Self::Incoming) {
|
|
if let Err(_) = ctx.send_to(self.next, msg.next()) {
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let mut rt = Runtime::new();
|
|
let inbox: Inbox<RingMessage> = rt.new_inbox();
|
|
|
|
let mut next = rt
|
|
.spawn(RingActor::new(*inbox.addr()))
|
|
.expect("failed to spawn");
|
|
for _ in 0..500 {
|
|
let new = rt.spawn(RingActor::new(next)).expect("failed to spawn");
|
|
next = new;
|
|
}
|
|
rt.send_to(next, RingMessage { count: 0 })
|
|
.expect("failed to start message ring");
|
|
|
|
let msg: RingMessage;
|
|
loop {
|
|
match inbox.try_recv() {
|
|
Some(m) => {
|
|
msg = m;
|
|
break;
|
|
}
|
|
None => {
|
|
rt.tick();
|
|
}
|
|
}
|
|
}
|
|
|
|
println!("{msg:?}")
|
|
}
|