Skip to main content

acktor/
lib.rs

1//! A pure-Rust actor framework built on top of the [Tokio](https://tokio.rs) async runtime,
2//! inspired by Alice Ryhl's [Actors with Tokio](https://ryhl.io/blog/actors-with-tokio/).
3//!
4//! `acktor` builds on the patterns described in Alice Ryhl's blog post and extends them into a
5//! structured library. Each actor runs as an independent `tokio` task with its own mailbox,
6//! processing messages one at a time. Actors communicate exclusively through message passing —
7//! there is no shared mutable state. The framework provides lifecycle hooks, supervision, an
8//! observer pattern, and support for periodic tasks.
9//!
10//! # Quick Start
11//!
12//! An example `Counter` actor that handles arithmetic messages might be the following:
13//!
14//! ```rust
15//! use acktor::{Actor, Context, Handler, Message, Signal};
16//!
17//! #[derive(Debug)]
18//! struct Counter(i64);
19//!
20//! impl Actor for Counter {
21//!     type Context = Context<Self>;
22//!     type Error = String;
23//! }
24//!
25//! #[derive(Debug, Message)]
26//! #[result_type(i64)]
27//! enum CounterMsg {
28//!     Increment,
29//!     Get,
30//! }
31//!
32//! impl Handler<CounterMsg> for Counter {
33//!     type Result = i64;
34//!
35//!     async fn handle(&mut self, msg: CounterMsg, _ctx: &mut Self::Context) -> i64 {
36//!         match msg {
37//!             CounterMsg::Increment => self.0 += 1,
38//!             CounterMsg::Get => {}
39//!         }
40//!         self.0
41//!     }
42//! }
43//!
44//! async fn run() {
45//!     let (addr, handle) = Counter(0).run("counter").unwrap();
46//!
47//!     // fire-and-forget
48//!     addr.do_send(CounterMsg::Increment).await.unwrap();
49//!
50//!     // request-reply
51//!     let result = addr.send(CounterMsg::Get).await.unwrap().await.unwrap();
52//!     println!("Counter: {result}"); // Counter: 1
53//!
54//!     addr.do_send(Signal::Stop).await.unwrap();
55//!     handle.await.unwrap();
56//! }
57//! ```
58//!
59//! # Feature Flags
60//!
61//! | Feature | Default | Description |
62//! |---------|---------|-------------|
63//! | `derive` | Yes | Enables `#[derive(Message)]` and `#[derive(MessageResponse)]` macros. |
64//! | `tokio-tracing` | No | Names spawned actor tasks for [`tokio-console`](https://docs.rs/console-subscriber). Requires building with `RUSTFLAGS="--cfg tokio_unstable"`. |
65//! | `bottleneck-warning` | No | Emits `tracing::debug!` logs when an observer's mailbox is full during notification, useful for spotting slow consumers. |
66//!
67
68#![cfg_attr(docsrs, feature(doc_cfg))]
69
70mod errors;
71pub use errors::{BoxError, ErrorReport, RecvError, SendError};
72
73pub mod channel;
74
75pub mod utils;
76
77#[doc(hidden)]
78pub mod actor;
79pub use actor::{Actor, ActorContext, ActorId, ActorState, JoinHandle, Stopping};
80
81mod context;
82pub use context::{Context, DEFAULT_MAILBOX_CAPACITY};
83
84pub mod address;
85pub use address::{Address, Recipient, Sender, SenderId};
86
87pub mod message;
88pub use message::{Handler, Message, MessageResponse};
89
90pub mod envelope;
91
92mod signal;
93pub use signal::Signal;
94
95pub mod supervisor;
96
97#[cfg(feature = "observer")]
98#[cfg_attr(docsrs, doc(cfg(feature = "observer")))]
99pub mod observer;
100
101#[cfg(feature = "cron")]
102#[cfg_attr(docsrs, doc(cfg(feature = "cron")))]
103pub mod cron;
104
105#[cfg(feature = "derive")]
106#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
107pub use acktor_derive::{Message, MessageResponse};
108
109#[cfg(test)]
110mod test_utils {
111    use crate::actor::Actor;
112    use crate::context::Context;
113    use crate::message::{Handler, Message};
114
115    #[derive(Debug)]
116    pub struct Dummy;
117
118    impl Actor for Dummy {
119        type Context = Context<Self>;
120        type Error = anyhow::Error;
121    }
122
123    #[derive(Debug)]
124    pub struct Ping(pub u32);
125
126    impl Message for Ping {
127        type Result = ();
128    }
129
130    impl Handler<Ping> for Dummy {
131        type Result = ();
132
133        async fn handle(&mut self, _msg: Ping, _ctx: &mut Self::Context) {}
134    }
135}