Trait simpl_actor::Actor

source ·
pub trait Actor: Sized {
    type Error: Send;

    // Provided methods
    fn channel_size() -> usize { ... }
    fn pre_start<'life0, 'async_trait>(
        &'life0 mut self
    ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
       where Self: Send + 'async_trait,
             'life0: 'async_trait { ... }
    fn pre_restart<'life0, 'async_trait>(
        &'life0 mut self,
        _err: Box<dyn Any + Send>
    ) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + Send + 'async_trait>>
       where Self: Send + 'async_trait,
             'life0: 'async_trait { ... }
    fn pre_stop<'async_trait>(
        self,
        _reason: ActorStopReason<Self::Error>
    ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
       where Self: Send + 'async_trait { ... }
}
Expand description

Defines the core functionality for actors within an actor-based concurrency model.

Implementors of this trait can leverage asynchronous task execution, lifecycle management hooks, and custom error handling.

This can be implemented with default behaviour using the Actor derive macro.

§Example

#[async_trait]
impl Actor for MyActor {
    type Error = ();

    async fn pre_start(&mut self) -> Result<(), Self::Error> {
        // actor is about to start up initially
        Ok(())
    }

    async fn pre_restart(&mut self, err: Box<dyn Any + Send>) -> Result<bool, Self::Error> {
        // actor panicked, return true if the actor should be restarted
        Ok(true)
    }

    async fn pre_stop(self, reason: ActorStopReason<Self::Error>) -> Result<(), Self::Error> {
        // actor is being stopped, any cleanup code can go here
        Ok(())
    }
}

Required Associated Types§

source

type Error: Send

The error type that can be returned from the actor’s methods.

Provided Methods§

source

fn channel_size() -> usize

Specifies the default size of the actor’s message channel.

This method can be overridden to change the size of the mailbox, affecting how many messages can be queued before backpressure is applied.

§Returns

The size of the message channel. The default is 64.

Examples found in repository?
examples/counter.rs (line 87)
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
async fn main() {
    let counter = CounterActor::new();
    let actor = counter.spawn();

    // Increment
    assert_eq!(actor.inc(2).await, Ok(()));
    // Count should be 2
    assert_eq!(actor.count().await, Ok(2));

    // Trigger the actor to sleep for 500ms in the background
    assert_eq!(actor.sleep_async().await, Ok(()));
    // Fill the mailbox with messages
    for _ in 0..CounterActor::channel_size() {
        assert_eq!(actor.inc_async(1).await, Ok(()));
    }
    // Mailbox should be full, so if we try to send a message without backpressure using the try_ method,
    // we should get an error that the mailbox is full
    assert_eq!(actor.try_inc(1).await, Err(ActorError::MailboxFull(1)));
    // And if we try to increment, waiting for 200ms for there to be capacity, we should timeout since the actor was sleeping for 500ms
    assert_eq!(
        actor.inc_timeout(1, Duration::from_millis(200)).await,
        Err(ActorError::Timeout(1))
    );

    // If a panic occurs when running a message, we should receive an error that the actor was sopped
    assert_eq!(actor.force_panic().await, Err(ActorError::ActorStopped));
    // But we've implemented the `Actor::pre_restart` method to return `true`, so the actor will be restarted,
    // and new messages should be handled sucessfully, even with the state being preserved
    assert_eq!(actor.inc(1).await, Ok(()));
    assert_eq!(actor.count().await, Ok(67));

    // Stop the actor, dropping any pending messages
    actor.stop_immediately();
    // Await the actor to stop
    actor.wait_for_stop().await;
    // Any new messages should error since the actor is no longer running
    assert_eq!(actor.inc(1).await, Err(ActorError::ActorNotRunning(1)));
}
source

fn pre_start<'life0, 'async_trait>( &'life0 mut self ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: Send + 'async_trait, 'life0: 'async_trait,

Hook that is called before the actor starts processing messages.

This asynchronous method allows for initialization tasks to be performed before the actor starts receiving messages.

§Returns

A result indicating successful initialization or an error if initialization fails.

source

fn pre_restart<'life0, 'async_trait>( &'life0 mut self, _err: Box<dyn Any + Send> ) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + Send + 'async_trait>>
where Self: Send + 'async_trait, 'life0: 'async_trait,

Hook that is called when an actor is about to be restarted after an error.

This method provides an opportunity to clean up or reset state before the actor is restarted. It can also determine whether the actor should actually be restarted based on the nature of the error.

§Parameters
  • err: The error that caused the actor to be restarted.
§Returns

A boolean indicating whether the actor should be restarted (true) or not (false).

source

fn pre_stop<'async_trait>( self, _reason: ActorStopReason<Self::Error> ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: Send + 'async_trait,

Hook that is called before the actor is stopped.

This method allows for cleanup and finalization tasks to be performed before the actor is fully stopped. It can be used to release resources, notify other actors, or complete any final tasks.

§Parameters
  • reason: The reason why the actor is being stopped.
§Returns

A result indicating the successful cleanup or an error if the cleanup process fails.

Object Safety§

This trait is not object safe.

Implementors§