Expand description
§rsActor
A Lightweight Rust Actor Framework with Simple Yet Powerful Task Control
rsActor is a lightweight, Tokio-based actor framework in Rust focused on providing simple
yet powerful task control. It prioritizes simplicity and efficiency for local, in-process
actor systems while giving developers complete control over their actors’ execution lifecycle —
define your own run_loop, control execution, control the lifecycle.
§Features
- Asynchronous Actors: Actors run in their own asynchronous tasks.
- Message Passing: Actors communicate by sending and receiving messages.
tell: Send a message without waiting for a reply (fire-and-forget).ask: Send a message and await a reply.tell_blocking: Blocking version oftellfor use intokio::task::spawn_blockingtasks.ask_blocking: Blocking version ofaskfor use intokio::task::spawn_blockingtasks.
- Actor Lifecycle with Simple Yet Powerful Task Control: Actors have
on_start,on_stop, andrun_looplifecycle hooks. The distinctiverun_loopfeature provides a dedicated task execution environment that users can control with simple yet powerful primitives, unlike other actor frameworks. This gives developers complete control over their actor’s task logic while the framework manages the underlying execution. - Graceful Shutdown & Kill: Actors can be stopped gracefully or killed immediately.
- Typed Messages: Messages are strongly typed, and replies are also typed.
- Macro for Message Handling: The
impl_message_handler!macro simplifies handling multiple message types.
§Core Concepts
Actor: Trait defining actor behavior and lifecycle hooks (on_start,on_stop,run_loop).Message<M>: Trait for handling a message typeMand defining its reply type.ActorRef: Handle for sending messages to an actor.spawn: Function to create and start an actor, returning anActorRefand aJoinHandle.MessageHandler: Trait for type-erased message handling. This is typically implemented automatically by theimpl_message_handler!macro.MailboxMessage(Internal): Enum for messages in an actor’s mailbox (user messages and control signals).Runtime(Internal): Manages an actor’s internal lifecycle and message loop.
§Getting Started
Define an actor struct, implement Actor and Message<M> for each message type.
Use impl_message_handler! to wire up message handling.
All Actor lifecycle methods (on_start, on_stop, run_loop) are optional
and have default implementations.
use rsactor::{Actor, ActorRef, Message, impl_message_handler, spawn};
use anyhow::Result;
// 1. Define your actor struct
struct MyActor {
data: String,
}
impl MyActor {
fn new(data: &str) -> Self {
MyActor { data: data.to_string() }
}
}
// 2. Implement the Actor trait (on_start, on_stop, on_run are optional)
impl Actor for MyActor {
type Error = anyhow::Error; // Define an error type
// Optional: Implement on_start for initialization
// async fn on_start(&mut self, _actor_ref: &ActorRef) -> Result<(), Self::Error> {
// println!("MyActor (data: '{}') started!", self.data);
// Ok(())
// }
// Optional: Implement on_stop for cleanup
// async fn on_stop(&mut self, _actor_ref: &ActorRef, _reason: &rsactor::ActorStopReason) -> Result<(), Self::Error> {
// println!("MyActor (data: '{}') stopped!", self.data);
// Ok(())
// }
// Optional: Implement run_loop for the actor's main execution logic.
// This method is called after on_start. If it returns Ok(()), the actor stops normally.
// If it returns Err(_), the actor stops due to an error.
// async fn run_loop(&mut self, _actor_ref: &ActorRef) -> Result<(), Self::Error> {
// // Example: Perform some work in a loop or a long-running task.
// // loop {
// // tokio::time::sleep(std::time::Duration::from_secs(1)).await;
// // // if some_condition { break; } // Or return Ok(()) to stop.
// // }
// Ok(()) // Actor stops when run_loop completes.
// }
}
// 3. Define your message types
struct GetData; // A message to get the actor's data
struct UpdateData(String); // A message to update the actor's data
// 4. Implement Message<M> for each message type
impl Message<GetData> for MyActor {
type Reply = String; // This message will return a String
async fn handle(&mut self, _msg: GetData, _actor_ref: &ActorRef) -> Self::Reply {
self.data.clone()
}
}
impl Message<UpdateData> for MyActor {
type Reply = (); // This message does not return a value
async fn handle(&mut self, msg: UpdateData, _actor_ref: &ActorRef) -> Self::Reply {
self.data = msg.0;
println!("MyActor data updated!");
}
}
// 5. Use the macro to implement the MessageHandler trait
impl_message_handler!(MyActor, [GetData, UpdateData]);
#[tokio::main]
async fn main() -> Result<()> {
let my_actor = MyActor::new("initial data");
let (actor_ref, join_handle) = spawn(my_actor);
// Send an "ask" message and wait for a reply
let current_data: String = actor_ref.ask(GetData).await?;
println!("Received data: {}", current_data);
// Send a "tell" message (fire-and-forget)
actor_ref.tell(UpdateData("new data".to_string())).await?;
// Verify the update
let updated_data: String = actor_ref.ask(GetData).await?;
println!("Updated data: {}", updated_data);
// Stop the actor gracefully
actor_ref.stop().await?;
// Wait for the actor to terminate
let (_actor_instance, stop_reason) = join_handle.await?;
println!("Actor stopped with reason: {:?}", stop_reason);
Ok(())
}This crate-level documentation provides an overview of rsactor.
For more details on specific components, please refer to their individual
documentation.
Macros§
- impl_
message_ handler - Implements the
MessageHandlertrait for a given actor type.
Structs§
- Actor
Ref - A reference to an actor, allowing messages to be sent to it.
Enums§
- Actor
Stop Reason - Represents the reason an actor stopped.
Constants§
- DEFAULT_
MAILBOX_ CAPACITY - The default mailbox capacity for actors.
Traits§
- Actor
- Defines the behavior of an actor.
- Message
- A trait for messages that an actor can handle, defining the reply type.
- Message
Handler - A trait for type-erased message handling within the actor’s
Runtime.
Functions§
- set_
default_ mailbox_ capacity - Sets the global default buffer size for actor mailboxes.
- spawn
- Spawns a new actor and returns an
ActorRefto it, along with aJoinHandle. - spawn_
with_ mailbox_ capacity - Spawns a new actor with a specified mailbox capacity and returns an
ActorRefto it, along with aJoinHandle.