Skip to main content

actor

Attribute Macro actor 

Source
#[actor]
Expand description

Generates impl Actor and Handler<M> implementations from an annotated impl block.

Place #[actor] on an impl MyStruct block. The macro extracts annotated methods and generates the boilerplate needed to run the struct as an actor.

§Protocol Assertion

Use protocol = TraitName to verify at compile time that the actor fully implements a protocol (i.e., that ActorRef<Self> implements the protocol trait):

#[actor(protocol = NameServerProtocol)]
impl NameServer { /* ... */ }

The runtime (tasks vs threads) is inferred from whether any handler in the block is async fn. If all handlers are defined outside the #[actor] block, put at least one handler inside so the macro can detect the correct runtime.

For multiple protocols:

#[actor(protocol(RoomProtocol, UserProtocol))]
impl ChatUser { /* ... */ }

§Handler Attributes

AttributeUse for
#[request_handler]Messages that expect a reply (Response<T>)
#[send_handler]Fire-and-forget messages
#[handler]Generic handler (works for either kind)

Handler signature: fn name(&mut self, msg: MessageType, ctx: &Context<Self>) -> ReturnType

The return type must match the message’s Message::Result. For request handlers returning (), omit the return type.

§Lifecycle Hooks

AttributeCalled
#[started]After the actor starts, before processing messages
#[stopped]After the actor stops processing messages

Both receive &mut self and &Context<Self>. Use async or sync to match your runtime.

§Example

use spawned_concurrency::tasks::{Actor, Context, Handler};
use spawned_concurrency::actor;

pub struct MyActor { count: u64 }

#[actor(protocol = CounterProtocol)]
impl MyActor {
    pub fn new() -> Self { MyActor { count: 0 } }

    #[started]
    async fn on_start(&mut self, _ctx: &Context<Self>) {
        tracing::info!("Actor started");
    }

    #[send_handler]
    async fn handle_increment(&mut self, msg: Increment, _ctx: &Context<Self>) {
        self.count += msg.amount;
    }

    #[request_handler]
    async fn handle_get_count(&mut self, _msg: GetCount, _ctx: &Context<Self>) -> u64 {
        self.count
    }
}