Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Actor Recipe for Rust

CI Documentation

A recipe for building actor systems with minimal boilerplate and good observability.

Overview

This project demonstrates a complete actor system implementation in Rust, featuring:

  • 80% less boilerplate - Macro-generated client methods with automatic error handling
  • Professional observability - Request correlation across actors with timing
  • Clean architecture - Domain-specific actors with clear separation of concerns
  • Type-safe error handling - Domain-specific error types (UserError, ProductError, OrderError)
  • Test-friendly - Test-only messages for inspecting internal actor state
  • Production-ready - Error handling, graceful shutdown, and scaling patterns

Architecture

The system consists of three main actor types:

Sub-Actors (Domain-Specific)

  • UserService - Manages user data (create, get, update, list)
  • ProductService - Handles products and inventory (get, check stock, reserve)

Root Actor (Orchestrator)

  • OrderService - Coordinates user and product services to create orders

System Coordinator

  • OrderSystem - Manages lifecycle, dependency injection, and graceful shutdown

Key Features

Terminology

This implementation uses business-friendly terminology:

  • Service (e.g., UserService) = Actor
  • Client (e.g., UserClient) = Actor Reference/Handle

Macro-Generated Clients

The client_method! macro eliminates boilerplate for actor communication:

// This generates a complete client method with tracing:
client_method!(UserClient => fn get_user(id: String) -> Option<User> as UserRequest::GetUser);

// Equivalent to writing 15+ lines of boilerplate code manually

Comprehensive Tracing

All operations are automatically traced with structured logging:

INFO user_creation: Creating test user
DEBUG create_user{}: Sending request
DEBUG handle_create_user{user_name="Alice" user_email="alice@example.com"}: Processing create_user request
INFO handle_create_user{user_name="Alice" user_email="alice@example.com"}: User created successfully user_id="user_1"

Handler Patterns

Multiple patterns for different operation types:

Usage

Running the Example

# Basic run
cargo run

# With debug logging
RUST_LOG=debug cargo run

# With warning level only
RUST_LOG=warn cargo run

Using in Your Code

// Create the entire order system
let system = OrderSystem::new();

// Create a user (flows to UserService)
let user = User::new("Alice", "alice@example.com");
let user_id = system.user_client.create_user(user).await?;

let order = Order::new("order_1", user_id, "p1", 5, 50.0);

// Process order (orchestrates UserService + ProductService, fails - no products in demo)
match system.order_client.create_order(order).await {
    Ok(order_id) => println!("Order created: {}", order_id),
    Err(e) => println!("Order failed (expected): {}", e),
}

// Shutdown gracefully
system.shutdown().await?;

Generating Documentation

# Generate and open documentation
cargo doc --open

Project Structure

src/
└── actor_recipe.rs    # Complete implementation with extensive documentation

The single file contains:

Dependencies

  • tokio - Async runtime with full features
  • tracing - Structured logging
  • tracing-subscriber - Log formatting and filtering

License

This is a reference implementation and recipe - use it as a foundation for your own actor systems.

About

A Rust Actor

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages