Trait aurum_actors::core::Actor [−][src]
pub trait Actor<U: Case<S> + UnifiedType, S: Send + RootMessage<U>> where
Self: Send + 'static, { fn recv<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 ActorContext<U, S>,
msg: S
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait; fn pre_start<'life0, 'life1, 'async_trait>(
&'life0 mut self,
__arg1: &'life1 ActorContext<U, S>
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
Self: Send + 'async_trait, { ... } fn post_stop<'life0, 'life1, 'async_trait>(
&'life0 mut self,
__arg1: &'life1 ActorContext<U, S>
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where
'life0: 'async_trait,
'life1: 'async_trait,
Self: Send + 'async_trait, { ... } }
Expand description
Defines how actors process messages.
Each actor runs on at least one asynchronous task. Messages are received and processed
atomically. Actors are lightweight and have good scalability locally.
Node
uses the Tokio
runtime to schedule its tasks.
Aurum operates under the same rules as Rust’s (and Tokio’s) asynchrony: tasks are IO-bound.
Code running in tasks is expected to await
often, and starvation can occur if asynchronous
code performs heavy compute operations or synchronous IO.
It is recommended to implement Actor
the async_trait
annotation. Rust cannot have async functions in traits yet, so this is a temporary work-around.
async_trait
changes the type signatures of the member funtions
for Actor
. Just pretend the trait looks like this instead of the monstrosity below:
pub trait Actor<U: Case<S> + UnifiedType, S: Send + RootMessage<U>> where Self: Send + 'static, { async fn pre_start(&mut self, _: &ActorContext<U, S>) {} async fn recv(&mut self, ctx: &ActorContext<U, S>, msg: S); async fn post_stop(&mut self, _: &ActorContext<U, S>) {} }
You’ll need to use async_trait
for every implementation of
Actor
.
use async_trait::async_trait; use aurum_actors::AurumInterface; use aurum_actors::core::{Actor, ActorContext, ActorRef, Case, UnifiedType}; use serde::{Serialize, Deserialize}; #[derive(AurumInterface, Serialize, Deserialize)] #[serde(bound = "U: UnifiedType")] enum Ball<U: UnifiedType + Case<Ball<U>>> { Ping(ActorRef<U, Self>), Pong(ActorRef<U, Self>), } struct Player<U: UnifiedType + Case<Ball<U>>> { initial_contact: Option<ActorRef<U, Ball<U>>> } #[async_trait] impl<U: UnifiedType + Case<Ball<U>>> Actor<U, Ball<U>> for Player<U> { async fn pre_start(&mut self, ctx: &ActorContext<U, Ball<U>>) { if let Some(r) = &self.initial_contact { r.remote_send(&ctx.node, &Ball::Ping(ctx.interface())).await; } } async fn recv(&mut self, ctx: &ActorContext<U, Ball<U>>, msg: Ball<U>) { match msg { Ball::Ping(r) => { r.remote_send(&ctx.node, &Ball::Pong(ctx.interface())).await; } Ball::Pong(r) => { r.remote_send(&ctx.node, &Ball::Ping(ctx.interface())).await; } } } }
Required methods
Provided methods
A setup function. This is called before the actor starts receiving messages.
Called when the actor terminates gracefully and has stopped receiving messages.
Implementors
impl<U, S> Actor<U, CausalMsg<S>> for CausalDisperse<S, U> where
U: UnifiedType + Case<CausalMsg<S>> + Case<CausalIntraMsg<S>>,
S: CRDT,