Skip to main content

ThreadLocalActor

Trait ThreadLocalActor 

Source
pub trait ThreadLocalActor:
    Sized
    + Default
    + 'static {
    type Msg: Message;
    type State;
    type Arguments: State;

    // Required method
    fn pre_start(
        &self,
        myself: ActorRef<Self::Msg>,
        args: Self::Arguments,
    ) -> impl Future<Output = Result<Self::State, Box<dyn Error + Sync + Send>>>;

    // Provided methods
    fn post_start(
        &self,
        myself: ActorRef<Self::Msg>,
        state: &mut Self::State,
    ) -> impl Future<Output = Result<(), Box<dyn Error + Sync + Send>>> { ... }
    fn post_stop(
        &self,
        myself: ActorRef<Self::Msg>,
        state: &mut Self::State,
    ) -> impl Future<Output = Result<(), Box<dyn Error + Sync + Send>>> { ... }
    fn handle(
        &self,
        myself: ActorRef<Self::Msg>,
        message: Self::Msg,
        state: &mut Self::State,
    ) -> impl Future<Output = Result<(), Box<dyn Error + Sync + Send>>> { ... }
    fn handle_supervisor_evt(
        &self,
        myself: ActorRef<Self::Msg>,
        message: SupervisionEvent,
        state: &mut Self::State,
    ) -> impl Future<Output = Result<(), Box<dyn Error + Sync + Send>>> { ... }
    fn spawn(
        name: Option<String>,
        startup_args: Self::Arguments,
        spawner: ThreadLocalActorSpawner,
    ) -> impl Future<Output = Result<(ActorRef<Self::Msg>, JoinHandle<()>), SpawnErr>> { ... }
    fn spawn_instant(
        name: Option<String>,
        startup_args: Self::Arguments,
        spawner: ThreadLocalActorSpawner,
    ) -> Result<(ActorRef<Self::Msg>, JoinHandle<Result<JoinHandle<()>, SpawnErr>>), SpawnErr> { ... }
    fn spawn_linked(
        name: Option<String>,
        startup_args: Self::Arguments,
        supervisor: ActorCell,
        spawner: ThreadLocalActorSpawner,
    ) -> impl Future<Output = Result<(ActorRef<Self::Msg>, JoinHandle<()>), SpawnErr>> { ... }
    fn spawn_linked_instant(
        name: Option<String>,
        startup_args: Self::Arguments,
        supervisor: ActorCell,
        spawner: ThreadLocalActorSpawner,
    ) -> Result<(ActorRef<Self::Msg>, JoinHandle<Result<JoinHandle<()>, SpawnErr>>), SpawnErr> { ... }
}
Expand description

ThreadLocalActor defines the behavior of an Actor. It specifies the Message type, State type, and all processing logic for the actor

NOTE: All of the implemented trait functions

  • pre_start
  • post_start
  • post_stop
  • handle
  • handle_serialized (Available with cluster feature only)
  • handle_supervisor_evt

return a Result<_, ActorProcessingError> where the error type is an alias of [Box<dyn std::error::Error + Send + Sync + ’static>]. This is treated as an “unhandled” error and will terminate the actor + execute necessary supervision patterns. Panics are also captured from the inner functions and wrapped into an Error type, however should an [Err(_)] result from any of these functions the actor will terminate and cleanup.

§Example

use ractor::thread_local::ThreadLocalActor;
use ractor::thread_local::ThreadLocalActorSpawner;
use ractor::ActorProcessingErr;
use ractor::ActorRef;

#[derive(Default)]
struct TheActor;

impl ThreadLocalActor for TheActor {
    type Msg = ();
    type Arguments = String;
    type State = String;

    async fn pre_start(
        &self,
        _myself: ActorRef<Self::Msg>,
        args: Self::Arguments,
    ) -> Result<Self::State, ActorProcessingErr> {
        Ok(args)
    }

    async fn handle(
        &self,
        _myself: ActorRef<Self::Msg>,
        _msg: (),
        state: &mut Self::State,
    ) -> Result<(), ActorProcessingErr> {
        println!("Message! {state}");
        Ok(())
    }
}

#[tokio::main]
async fn main() {
    // Create the thread-local spawner
    let spawner = ThreadLocalActorSpawner::new();
    // spawn the actor
    let (who, handle) =
        ractor::spawn_local::<TheActor>("Something".to_string(), spawner.clone())
            .await
            .expect("Failed to spawn thread-local actor!");

    // send messages to the actor
    who.cast(()).expect("Failed to send");
    who.cast(()).expect("Failed to send");

    // Tell the actor to drain then stop
    who.drain();

    // wait for the termination
    handle.await.unwrap();
}

Required Associated Types§

Source

type Msg: Message

The message type for this actor

Source

type State

The type of state this actor manages internally. This type has no bound requirements, and needs to neither be Send nor Sync when used in a ThreadLocalActor context.

Source

type Arguments: State

Initialization arguments. These must be Send as they are sent to the pinned thread in order to startup the actor. However the actor’s local ThreadLocalActor::State does NOT need to be Send and neither does the actor instance.

Required Methods§

Source

fn pre_start( &self, myself: ActorRef<Self::Msg>, args: Self::Arguments, ) -> impl Future<Output = Result<Self::State, Box<dyn Error + Sync + Send>>>

Invoked when an actor is being started by the system.

Any initialization inherent to the actor’s role should be performed here hence why it returns the initial state.

Panics in pre_start do not invoke the supervision strategy and the actor won’t be started. ThreadLocalActor::spawn will return an error to the caller

  • myself - A handle to the ActorCell representing this actor
  • args - Arguments that are passed in the spawning of the actor which might be necessary to construct the initial state

Returns an initial ThreadLocalActor::State to bootstrap the actor

Provided Methods§

Source

fn post_start( &self, myself: ActorRef<Self::Msg>, state: &mut Self::State, ) -> impl Future<Output = Result<(), Box<dyn Error + Sync + Send>>>

Invoked after an actor has started.

Any post initialization can be performed here, such as writing to a log file, emitting metrics.

Panics in post_start follow the supervision strategy.

  • myself - A handle to the ActorCell representing this actor
  • state - A mutable reference to the internal actor’s state
Source

fn post_stop( &self, myself: ActorRef<Self::Msg>, state: &mut Self::State, ) -> impl Future<Output = Result<(), Box<dyn Error + Sync + Send>>>

Invoked after an actor has been stopped to perform final cleanup. In the event the actor is terminated with Signal::Kill or has self-panicked, post_stop won’t be called.

Panics in post_stop follow the supervision strategy.

  • myself - A handle to the ActorCell representing this actor
  • state - A mutable reference to the internal actor’s last known state
Source

fn handle( &self, myself: ActorRef<Self::Msg>, message: Self::Msg, state: &mut Self::State, ) -> impl Future<Output = Result<(), Box<dyn Error + Sync + Send>>>

Handle the incoming message from the event processing loop. Unhandled panickes will be captured and sent to the supervisor(s)

  • myself - A handle to the ActorCell representing this actor
  • message - The message to process
  • state - A mutable reference to the internal actor’s state
Source

fn handle_supervisor_evt( &self, myself: ActorRef<Self::Msg>, message: SupervisionEvent, state: &mut Self::State, ) -> impl Future<Output = Result<(), Box<dyn Error + Sync + Send>>>

Handle the incoming supervision event. Unhandled panics will be captured and sent the the supervisor(s). The default supervision behavior is to exit the supervisor on any child exit. To override this behavior, implement this function.

  • myself - A handle to the ActorCell representing this actor
  • message - The message to process
  • state - A mutable reference to the internal actor’s state
Source

fn spawn( name: Option<String>, startup_args: Self::Arguments, spawner: ThreadLocalActorSpawner, ) -> impl Future<Output = Result<(ActorRef<Self::Msg>, JoinHandle<()>), SpawnErr>>

Spawn an actor of this type, which is unsupervised, automatically starting

  • name: A name to give the actor. Useful for global referencing or debug printing
  • startup_args: Arguments passed to the pre_start call of the ThreadLocalActor to facilitate startup and initial state creation
  • spawner: The ThreadLocalActorSpawner which will control starting this actor on a specific thread

Returns a [Ok((ActorRef, JoinHandle<()>))] upon successful start, denoting the actor reference along with the join handle which will complete when the actor terminates. Returns [Err(SpawnErr)] if the actor failed to start

Source

fn spawn_instant( name: Option<String>, startup_args: Self::Arguments, spawner: ThreadLocalActorSpawner, ) -> Result<(ActorRef<Self::Msg>, JoinHandle<Result<JoinHandle<()>, SpawnErr>>), SpawnErr>

Spawn an actor instantly, not waiting on the actor’s pre_start routine.

Returns a [Ok((ActorRef, JoinHandle<Result<JoinHandle<()>, SpawnErr>>))] upon successful creation of the message queues, so you can begin sending messages. However the associated JoinHandle contains the inner information around if the actor successfully started or not in it’s pre_start routine. Returns [Err(SpawnErr)] if the actor name is already allocated

Source

fn spawn_linked( name: Option<String>, startup_args: Self::Arguments, supervisor: ActorCell, spawner: ThreadLocalActorSpawner, ) -> impl Future<Output = Result<(ActorRef<Self::Msg>, JoinHandle<()>), SpawnErr>>

Spawn an actor of this type with a supervisor, automatically starting the actor

  • name: A name to give the actor. Useful for global referencing or debug printing
  • startup_args: Arguments passed to the pre_start call of the ThreadLocalActor to facilitate startup and initial state creation
  • supervisor: The ActorCell which is to become the supervisor (parent) of this actor
  • spawner: The ThreadLocalActorSpawner which will control starting this actor on a specific thread

Returns a [Ok((ActorRef, JoinHandle<()>))] upon successful start, denoting the actor reference along with the join handle which will complete when the actor terminates. Returns [Err(SpawnErr)] if the actor failed to start

Source

fn spawn_linked_instant( name: Option<String>, startup_args: Self::Arguments, supervisor: ActorCell, spawner: ThreadLocalActorSpawner, ) -> Result<(ActorRef<Self::Msg>, JoinHandle<Result<JoinHandle<()>, SpawnErr>>), SpawnErr>

Spawn an actor instantly with a supervisor, not waiting on the actor’s pre_start routine.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<T> ThreadLocalActor for T
where T: Actor + Default,

Source§

type Msg = <T as Actor>::Msg

Source§

type State = <T as Actor>::State

Source§

type Arguments = <T as Actor>::Arguments