[−][src]Trait xtra_addons::Actor
An actor which can handle Message
s one at a time. Actors can only be
communicated with by sending Message
s through their Address
es.
They can modify their private state, respond to messages, and spawn other actors. They can also
stop themselves through their Context
by calling Context::stop
.
This will result in any attempt to send messages to the actor in future failing.
This is an async_trait
, so implementations should
be annotated #[async_trait]
.
Example
struct MyActor; #[async_trait::async_trait] impl Actor for MyActor { async fn started(&mut self, ctx: &mut Context<Self>) { println!("Started!"); } async fn stopping(&mut self, ctx: &mut Context<Self>) -> KeepRunning { println!("Decided not to keep running"); KeepRunning::StopAll } async fn stopped(&mut self) { println!("Finally stopping."); } } struct Goodbye; impl Message for Goodbye { type Result = (); } #[async_trait::async_trait] impl Handler<Goodbye> for MyActor { async fn handle(&mut self, _: Goodbye, ctx: &mut Context<Self>) { println!("Goodbye!"); ctx.stop(); } } // Will print "Started!", "Goodbye!", "Decided not to keep running", and then "Finally stopping." smol::block_on(async { let addr = MyActor.create(None).spawn(&mut Smol::Global); addr.send(Goodbye).await; Timer::after(Duration::from_secs(1)).await; // Give it time to run })
For longer examples, see the examples
directory.
Provided methods
#[must_use]pub fn started<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 mut Context<Self>
) -> Pin<Box<dyn Future<Output = ()> + 'async_trait + Send, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
[src]
&'life0 mut self,
ctx: &'life1 mut Context<Self>
) -> Pin<Box<dyn Future<Output = ()> + 'async_trait + Send, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Called as soon as the actor has been started.
#[must_use]pub fn stopping<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 mut Context<Self>
) -> Pin<Box<dyn Future<Output = KeepRunning> + 'async_trait + Send, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
[src]
&'life0 mut self,
ctx: &'life1 mut Context<Self>
) -> Pin<Box<dyn Future<Output = KeepRunning> + 'async_trait + Send, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Called when the actor calls the Context::stop
. This method
can prevent the actor from stopping by returning KeepRunning::Yes
.
If this method returns KeepRunning::StopSelf
,
this actor will be stopped. If it returns
KeepRunning::StopAll
, then all actors on the same
address as this actor will be stopped. This can take a little bit of time to propagate.
Note: this method will only be called when Context::stop
is called from this actor. If the last strong address to the actor is dropped, or
Context::stop
is called from another actor on the same
address, this will not be called. Therefore, Other, general destructor behaviour should be
encapsulated in the Actor::stopped
method.
Example
async fn stopping(&mut self, ctx: &mut Context<Self>) -> KeepRunning { self.is_running.into() // bool can be converted to KeepRunning with Into }
#[must_use]pub fn stopped<'life0, 'async_trait>(
&'life0 mut self
) -> Pin<Box<dyn Future<Output = ()> + 'async_trait + Send, Global>> where
'life0: 'async_trait,
Self: 'async_trait,
[src]
&'life0 mut self
) -> Pin<Box<dyn Future<Output = ()> + 'async_trait + Send, Global>> where
'life0: 'async_trait,
Self: 'async_trait,
Called when the actor is in the process of stopping. This could be because
KeepRunning::StopAll
or
KeepRunning::StopSelf
was returned from the
Actor::stopping
method, or because there are no more
strong addresses (Address
, as opposed to
WeakAddress
. This should be used for any final cleanup before
the actor is dropped.
pub fn create(self, message_cap: Option<usize>) -> ActorManager<Self>
[src]
Returns the actor's address and manager in a ready-to-start state, given the cap for the
actor's mailbox. If None
is passed, it will be of unbounded size. To spawn the actor,
the ActorManager::spawn
must be called, or
the ActorManager::run
method must be called
and the future it returns spawned onto an executor.
Example
smol::block_on(async { let (addr, fut) = MyActor.create(None).run(); smol::spawn(fut).detach(); // Actually spawn the actor onto an executor Timer::after(Duration::from_secs(1)).await; // Give it time to run })