Expand description
§actor-kit
A work-stealing actor runtime with OTP-style supervision, designed for hosting 100,000+ actors per node with efficient load balancing.
§How this differs from task-per-actor runtimes
Most Rust actor frameworks (ractor, kameo) run each actor as its own
tokio task: the async runtime multiplexes tasks onto its worker threads, and
“scheduling” is just task polling. actor-kit takes a different approach:
- Actors are not tasks. An actor is a registry entry (ID + state +
bounded mailbox). Work arrives as
Taskitems on crossbeam deques. - A fixed pool of OS worker threads pulls work from (1) a priority injector, (2) their local FIFO deque, (3) a global injector, then (4) steals from other workers — in that order. Idle workers back off (spin, then sleep) instead of burning a reactor tick per actor.
- Per-actor mailbox with hard backpressure. Bounded lock-free
ArrayQueue+ tokioSemaphore; senders block or fail once the mailbox crosses its backpressure threshold (default 80% of capacity). A hot actor cannot grow an unbounded task queue. - Supervision is data, not tasks. Erlang/OTP strategies
(OneForOne / OneForAll / RestForOne / SimpleOneForOne), restart
policies (Permanent / Transient / Temporary), max-restarts-within-window
rate limiting, escalation, and hierarchical
SupervisorTrees are plain data structures you drive explicitly — no hidden per-supervisor tokio tasks, no implicit restart side effects.
The trade-offs are honest: message handlers here are state-machine steps
(state lives in the registry, not in an async frame), so actors that need
to .await I/O mid-handler are a better fit for task-per-actor frameworks.
This runtime shines when you have very many mostly-CPU-light actors,
want predictable memory per actor, and need OTP-style fault tolerance
semantics with real work stealing.
§Example
use actor_kit::{ActorBuilder, ActorScheduler, MessagePayload, SchedulerConfig};
use std::sync::Arc;
// Create and start a 4-worker work-stealing scheduler.
let scheduler = Arc::new(ActorScheduler::new(SchedulerConfig::new().workers(4)));
scheduler.start()?;
// Spawn an actor and start it.
let handle = ActorBuilder::new().name("my-actor").spawn(&scheduler)?;
handle.start().await?;
// Send messages (backpressured, bounded mailbox).
handle.send(MessagePayload::Custom(vec![1, 2, 3])).await?;
assert!(handle.is_running());§Feature flags
std(default) — passthrough; the runtime is std-based.serde— typed RPC (rpcmodule), serde impls on public types.zero-copy— rkyv-backed zero-copy message path (zero_copymodule).unsafe-pool— bump-allocator memory pool (memory_poolmodule). The onlyunsafecode in the crate lives behind this flag.sim— deterministic simulation testing (simmodule): a seeded single-threaded scheduler replacement, virtual clock, fault injection, and seed-replay traces. TigerBeetle-style DST; see thesimmodule docs.full— all of the above.
The crate carries #![deny(unsafe_code)]; memory_pool (behind
unsafe-pool) is the single, loudly documented exception.
Re-exports§
pub use error::Error;pub use error::Result;pub use policy::NoopPolicy;pub use policy::ResourcePolicy;pub use queue::create_local_queue;pub use queue::PriorityQueue;pub use queue::WorkQueue;pub use queue::WorkStealer;pub use supervisor::ActorConfig;pub use supervisor::ChildSpec;pub use supervisor::ChildState;pub use supervisor::DegradationController;pub use supervisor::DegradationDecision;pub use supervisor::EscalationAction;pub use supervisor::ExitReason;pub use supervisor::FnResourceMonitor;pub use supervisor::PressureLevel;pub use supervisor::ResourceMonitor;pub use supervisor::RestartPolicy;pub use supervisor::StaticResourceMonitor;pub use supervisor::SupervisedChild;pub use supervisor::SupervisionStrategy;pub use supervisor::Supervisor;pub use supervisor::SupervisorError;pub use supervisor::SupervisorHandle;pub use supervisor::SupervisorStats;pub use supervisor::SupervisorTree;pub use supervisor::SupervisorTreeStats;
Modules§
- error
- Error types for the actor runtime.
- policy
- Pluggable admission-control hook for spawns and message sends.
- queue
- Lock-free work queue with work stealing support.
- supervisor
- Erlang-style supervisor trees for hierarchical actor supervision.
Structs§
- Actor
Builder - Builder for creating actors.
- Actor
Context - Context provided to actors during message handling.
- Actor
Handle - Handle to an actor for sending messages and querying state.
- ActorId
- Unique identifier for an actor.
- Actor
Registry - Actor registry for tracking actors.
- Actor
Scheduler - Work-stealing actor scheduler.
- Mailbox
- MPSC mailbox for an actor.
- Mailbox
Config - Configuration for an actor mailbox.
- Message
- A message sent to an actor.
- Null
Executor - Null executor for testing.
- Registry
Stats - Statistics about the actor registry.
- Scheduler
Config - Configuration for the actor scheduler.
- Scheduler
Stats - Statistics for the scheduler.
- Stealer
Registry - Shared stealer registry for work stealing between workers.
- Worker
Stats Info - Statistics for a worker.
Enums§
- Actor
State - State of an actor.
- Execution
Result - Result of executing an actor task.
- Message
Payload - Payload of a message.
- Priority
- Priority level for actor messages.
- Signal
- System signals.
Traits§
- Actor
- Trait for actor behavior.
- Actor
Executor - Trait for executing actor messages.