rsActor
A Simple and Efficient In-Process Actor Model Implementation for Rust.
rsActor is a lightweight, Tokio-based actor framework in Rust focused on providing a simple and efficient actor model for local, in-process systems. It emphasizes clean message-passing semantics and straightforward actor lifecycle management while maintaining high performance for Rust applications.
Note: This project is actively evolving. While core APIs are stable, some features may be refined in future releases.
Core Features
- Minimalist Actor System: Focuses on core actor model primitives.
- Message Passing:
ask/ask_with_timeout: Send a message and asynchronously await a reply.tell/tell_with_timeout: Send a message without waiting for a reply.ask_blocking/tell_blocking: Blocking versions fortokio::task::spawn_blockingcontexts.
- Straightforward Actor Lifecycle:
on_start,on_run, andon_stophooks provide a clean and intuitive actor lifecycle management system. The framework manages the execution flow while giving developers full control over actor behavior. - Graceful & Immediate Termination: Actors can be stopped gracefully or killed.
ActorResult: Enum representing the outcome of an actor's lifecycle (e.g., completed, failed).- Macro-Assisted Message Handling:
impl_message_handler!macro simplifies routing messages. - Tokio-Native: Built for the
tokioasynchronous runtime. - Only
SendTrait Required: Actor structs only need to implement theSendtrait (notSync), enabling the use of interior mutability types likestd::cell::Cellfor internal state management without synchronization overhead. TheActortrait andMessageHandlertrait (viaimpl_message_handler!macro) are also required, but they don't add any additional constraints on the actor's fields.
Getting Started
1. Add Dependency
[]
= "0.7" # Check crates.io for the latest version
2. Basic Usage Example
A simple counter actor:
use ;
use Result;
use info;
// Define actor struct
// Added Debug for printing the actor in ActorResult
// Implement Actor trait
// Define message types
;
;
// Implement Message<T> for IncrementMsg
// Implement Message<T> for GetCountMsg
// Use macro for message handling
impl_message_handler!;
async
Running the Example
Run the example from examples/basic.rs:
Using Blocking Functions with Tokio Tasks
ask_blocking and tell_blocking are for use within Tokio's blocking tasks (tokio::task::spawn_blocking).
When to Use
- Inside a
tokio::task::spawn_blockingtask.
Example
use ; // Assuming Actor is also in scope
use task;
use Duration;
use Result;
// Dummy message and actor for context
;
;
// Added for ActorResult
;
impl_message_handler!;
async
// To make this runnable, you'd need to spawn an actor and pass its ActorRef
// For example:
// #[tokio::main]
// async fn main() -> Result<()> {
// let (actor_ref, _join_handle) = rsactor::spawn::<MyActor>(()); // Pass empty args
// demonstrate_blocking_calls(actor_ref).await?;
// Ok(())
// }
Important: These functions require an active Tokio runtime.
Type Safety Features
rsActor provides two actor reference types:
ActorRef<T> - Compile-Time Type Safety
- Recommended for most use cases
- Only accepts messages the actor can handle (compile-time validation)
- Return types automatically inferred from trait implementations
- Zero runtime overhead
UntypedActorRef - Runtime Type Handling
- Use only when type erasure is needed
- Enables storing different actor types in collections
- Supports dynamic actor management and plugin systems
- Developer responsible for ensuring type safety at runtime
Conversion: You can get an UntypedActorRef from ActorRef<T> using typed_ref.untyped_actor_ref()
Further Information
For more detailed questions and answers, please see the FAQ.
License
This project is licensed under the Apache License 2.0. See the LICENSE-APACHE file for details.