A Simple Tiny Tokio Actor Crate
This crate provides a minimally functioning actor system with a common
event bus. Tokio unbounded channels are used for the mailbox of the
actors, and actor behaviour (defined through the Handler
trait) can
use the request+response pattern (using tokio oneshot channel for
responses). You an send messages to actors either through a tell
where the method does not provide a response, or an ask
. The ask
method does provide a response
Example
use tiny_tokio_actor::*;
#[derive(Clone)]
struct TestActor {
counter: usize
}
impl Actor for TestActor {}
#[derive(Clone, Debug)]
struct TestMessage(String);
impl Message for TestMessage {
type Response = String;
}
#[derive(Clone, Debug)]
struct TestEvent(String);
impl SystemEvent for TestEvent {}
#[async_trait]
impl Handler<TestMessage, TestEvent> for TestActor {
async fn handle(&mut self, msg: TestMessage, ctx: &mut ActorContext<TestEvent>) -> String {
self.counter += 1;
ctx.system.publish(TestEvent(format!("message received by '{}'", ctx.id)));
"Ping!".to_string()
}
}
#[tokio::main]
pub async fn main() {
let actor = TestActor { counter: 0 };
let msg = TestMessage("hello world!".to_string());
let bus = EventBus::<TestEvent>::new(1000);
let system = ActorSystem::new("test", bus);
let mut actor_ref = system.create_actor(actor).await;
let mut events = system.events();
tokio::spawn(async move {
loop {
match events.recv().await {
Ok(event) => println!("Received event! {:?}", event),
Err(err) => println!("Error receivng event!!! {:?}", err)
}
}
});
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
let response = actor_ref.ask(msg).await.unwrap();
println!("Response: {}", response);
}