Expand description
A pure-Rust actor framework built on top of the Tokio async runtime, inspired by Alice Ryhl’s Actors with Tokio.
acktor builds on the patterns described in Alice Ryhl’s blog post and extends them into a
structured library. Each actor runs as an independent tokio task with its own mailbox,
processing messages one at a time. Actors communicate exclusively through message passing —
there is no shared mutable state. The framework provides lifecycle hooks, supervision, an
observer pattern, and support for periodic tasks.
§Quick Start
An example Counter actor that handles arithmetic messages might be the following:
use acktor::{Actor, Context, Handler, Message, Signal};
#[derive(Debug)]
struct Counter(i64);
impl Actor for Counter {
type Context = Context<Self>;
type Error = String;
}
#[derive(Debug)]
enum CounterMsg {
Increment,
Get,
}
impl Message for CounterMsg {
type Result = i64;
}
impl Handler<CounterMsg> for Counter {
type Result = i64;
async fn handle(&mut self, msg: CounterMsg, _ctx: &mut Self::Context) -> i64 {
match msg {
CounterMsg::Increment => self.0 += 1,
CounterMsg::Get => {}
}
self.0
}
}
async fn start() {
let (addr, handle) = Counter(0).start("counter").unwrap();
// fire-and-forget
addr.do_send(CounterMsg::Increment).await.unwrap();
// request-reply
let result = addr.send(CounterMsg::Get).await.unwrap().await.unwrap();
println!("Counter: {}", result); // Counter: 1
addr.do_send(Signal::Stop).await.unwrap();
handle.await.unwrap();
}§Supervision
Implement Handler<SupervisionEvent<A>> on the supervisor actor. Use the command
Supervisor::Set to attach the supervisor actor to the child
(or Supervisor::Unset to detach). Since every actor handles
Supervisor<A> automatically, no extra wiring is needed on the child side.
use acktor::{Actor, Context, Handler, supervisor::SupervisionEvent};
struct Worker;
impl Actor for Worker {
type Context = Context<Self>;
type Error = String;
}
#[derive(Default)]
struct Watchdog;
impl Actor for Watchdog {
type Context = Context<Self>;
type Error = String;
}
impl Handler<SupervisionEvent<Worker>> for Watchdog {
type Result = ();
async fn handle(&mut self, event: SupervisionEvent<Worker>, _ctx: &mut Self::Context) {
println!("worker event: {:?}", event);
}
}§Observer
For a subject actor, implement the SubjectActor<Event> trait so it
can emit Events to registered observers. Every subject actor automatically gets a
Handler<Observer<Event>> implementation that manages the observers, so the observers can be
registered by sending Observer::Register commands to the
subject actor (or Observer::Unregister to stop receiving
events).
use acktor::{Actor, Context, Message, observer::{ObserverSet, SubjectActor}};
#[derive(Clone, Message)]
#[result_type(())]
struct Tick;
#[derive(Default)]
struct Clock { observers: ObserverSet<Tick> }
impl Actor for Clock {
type Context = Context<Self>;
type Error = String;
}
impl SubjectActor<Tick> for Clock {
fn observers_mut(&mut self) -> &mut ObserverSet<Tick> { &mut self.observers }
}§Cron Tasks
Use CronContext<Self> as the actor’s context and implement
CronActor trait to opt in this feature. CronActor trait defines a
task method that is invoked repeatedly with a delay determined by its return value.
use std::time::Duration;
use acktor::{Actor, cron::{CronActor, CronContext}};
struct Heartbeat;
impl Actor for Heartbeat {
type Context = CronContext<Self>;
type Error = String;
}
impl CronActor for Heartbeat {
async fn task(&mut self, _ctx: &mut Self::Context) -> Result<Duration, Self::Error> {
println!("tick");
Ok(Duration::from_secs(1))
}
}§Feature Flags
| Feature | Default | Description |
|---|---|---|
derive | Yes | Re-exports the derive macros from acktor-derive. |
observer | Yes | Enables the observer module. |
cron | Yes | Enables the cron module. |
identifier | No | Enables stable type identifiers (stable_type_id, MessageId). |
ipc | No | Enables IPC support: the codec module, BinaryMessage, remote addressing (RemoteAddressable, RemoteSpawnable, RemoteProxy), and the proto re-export. Implies identifier. |
prost-codec | No | Use an all-prost primitive codec instead of the default zerocopy + prost mix (useful for cross-language interop). |
bottleneck-warning | No | Emits tracing::debug! logs when an observer’s mailbox is full during notification, useful for spotting slow consumers. |
tokio-tracing | No | Names spawned actor tasks for tokio-console. Requires building with RUSTFLAGS="--cfg tokio_unstable". |
Re-exports§
pub use error::ErrorReport;pub use error::RecvError;pub use error::SendError;pub use stable_type_id::StableId;identifierpub use stable_type_id::StableTypeId;identifierpub use actor::Actor;pub use actor::ActorContext;pub use actor::ActorId;pub use actor::ActorState;pub use actor::Stopping;pub use actor::RemoteAddressable;ipcpub use actor::RemoteSpawnable;ipcpub use address::RemoteProxy;ipcpub use address::Address;pub use address::Recipient;pub use address::Sender;pub use address::SenderInfo;pub use message::MessageId;identifierpub use message::Handler;pub use message::Message;pub use message::MessageResponse;pub use acktor_ipc_proto as proto;ipc
Modules§
- actor
- Traits and type definitions for actors.
- address
- Traits and type definitions for actor address.
- channel
- Channel primitives used by this crate.
- codec
ipc - Codec traits for encoding and decoding remote messages.
- cron
cron - Repetitive task execution in an actor.
- envelope
- Traits and type definitions for the envelope of a message.
- error
- Error types used by this crate.
- message
- Message passing between actors.
- observer
observer - Observer pattern for actors.
- stable_
type_ id identifier - Stable type identifier.
- supervisor
- Supervision for actors.
- utils
- Utility functions and types used by this crate.
Structs§
- Context
- The default implementation of an actor context.
- Join
Handle - An owned permission to join on a task (await its termination).
Enums§
- Signal
- A message which is used to stop/terminate an actor.
Constants§
- DEFAULT_
MAILBOX_ CAPACITY - The default mailbox capacity for actors.
Attribute Macros§
- remote
deriveandipc - Attribute macro applies to the
impl Actor for MyActorblock, which overrides the internal methodActor::remote_mailboxto return aRemoteMailboxfor a remote addressable actor.
Derive Macros§
- Message
derive - Derive the
Messagetrait for a struct or enum. - Message
Id deriveandidentifier - Derive the
MessageIdtrait for aMessage. - Message
Response derive - Derive the
MessageResponsetrait for a struct or enum. - Remote
Addressable deriveandipc - Derive the
RemoteAddressabletrait for an actor. - Stable
Id deriveandidentifier - Derive the
StableIdtrait for a type.