use ractor::{async_trait, Actor, ActorProcessingErr, ActorRef, RpcReplyPort};
use tracing::{info, warn};
pub enum MyFirstActorMessage {
PrintHelloWorld,
HowManyHelloWorlds(RpcReplyPort<u16>),
}
pub struct MyFirstActor;
#[async_trait]
impl Actor for MyFirstActor {
type State = u16;
type Msg = MyFirstActorMessage;
type Arguments = ();
async fn pre_start(
&self,
_myself: ActorRef<Self::Msg>,
_arguments: Self::Arguments,
) -> Result<Self::State, ActorProcessingErr> {
Ok(0)
}
async fn handle(
&self,
_myself: ActorRef<Self::Msg>,
message: Self::Msg,
state: &mut Self::State,
) -> Result<(), ActorProcessingErr> {
match message {
MyFirstActorMessage::PrintHelloWorld => {
info!("Hello world!");
*state += 1;
}
MyFirstActorMessage::HowManyHelloWorlds(reply) => {
if reply.send(*state).is_err() {
warn!("Listener dropped their port before we could reply");
}
}
}
Ok(())
}
}
#[tokio::main]
async fn main() {
common_x::log::init_log_filter("debug");
let (actor, actor_handle) = Actor::spawn(Some("actor".to_string()), MyFirstActor, ())
.await
.expect("Actor failed to start");
for _i in 0..10 {
actor
.cast(MyFirstActorMessage::PrintHelloWorld)
.expect("Failed to send message to actor");
}
let hello_world_count =
ractor::call_t!(actor, MyFirstActorMessage::HowManyHelloWorlds, 100).expect("RPC failed");
info!("Actor replied with {} hello worlds!", hello_world_count);
actor.stop(None);
actor_handle.await.unwrap();
}