actor_sample/lifecycle/mod.rs
1//! # System Lifecycle & Orchestration
2//!
3//! This module manages the runtime lifecycle of actor-based systems, handling the complex
4//! coordination of starting, wiring, and shutting down multiple interdependent actors.
5//!
6//! ## The Orchestration Pattern
7//!
8//! In actor systems, individual actors are simple, but **wiring them together** is where
9//! complexity lives. This module provides the "conductor" that coordinates the entire system.
10//!
11//! **Key Responsibilities:**
12//! 1. **Actor Creation** - Instantiate all actors and their clients
13//! 2. **Dependency Injection** - Wire actors together via context injection
14//! 3. **Lifecycle Management** - Start actors in the correct order
15//! 4. **Graceful Shutdown** - Coordinate clean termination of all actors
16//! 5. **Observability Setup** - Initialize tracing and logging infrastructure
17//!
18//! ## The OrderSystem Pattern
19//!
20//! The [`OrderSystem`] demonstrates a complete lifecycle orchestrator:
21//!
22//! ```rust,ignore
23//! impl OrderSystem {
24//! pub fn new() -> Self {
25//! // 1. Create actors (no dependencies yet - avoids circular refs)
26//! let (user_actor, user_client) = user_actor::new();
27//! let (product_actor, product_client) = product_actor::new();
28//! let (order_actor, order_client) = order_actor::new();
29//!
30//! // 2. Start actors with their dependencies injected
31//! let user_handle = tokio::spawn(user_actor.run(()));
32//! let product_handle = tokio::spawn(product_actor.run(()));
33//! let order_handle = tokio::spawn(
34//! order_actor.run((user_client.clone(), product_client.clone()))
35//! );
36//!
37//! Self {
38//! user_client,
39//! product_client,
40//! order_client,
41//! handles: vec![user_handle, product_handle, order_handle],
42//! }
43//! }
44//!
45//! pub async fn shutdown(self) {
46//! // Drop clients to signal shutdown, then await all actors
47//! drop(self.user_client);
48//! drop(self.product_client);
49//! drop(self.order_client);
50//!
51//! for handle in self.handles {
52//! let _ = handle.await;
53//! }
54//! }
55//! }
56//! ```
57//!
58//! ## Dependency Injection via Context
59//!
60//! The framework uses **late binding** to solve circular dependency problems:
61//!
62//! - **Construction time**: Create actors without dependencies
63//! - **Runtime**: Inject dependencies via `run(context)`
64//!
65//! This pattern allows `Order` to depend on `User` and `Product` without creating
66//! circular references during construction.
67//!
68//! Each actor defines its `Context` associated type:
69//!
70//! ```rust,ignore
71//! // No dependencies
72//! impl ActorEntity for User {
73//! type Context = ();
74//! }
75//!
76//! // Depends on User and Product clients
77//! impl ActorEntity for Order {
78//! type Context = (UserClient, ProductClient);
79//! }
80//! ```
81//!
82//! ## Graceful Shutdown
83//!
84//! The shutdown pattern follows these steps:
85//!
86//! 1. **Drop all clients** - Closes the sender side of channels
87//! 2. **Actors detect closure** - `receiver.recv()` returns `None`
88//! 3. **Actors clean up** - Process remaining messages, log final state
89//! 4. **Await completion** - Wait for all actor tasks to finish
90//!
91//! This ensures no messages are lost and all actors terminate cleanly.
92//!
93//! **With Context Dependencies:** When actors hold clients in their context (e.g., `Order` actor has `UserClient` and
94//! `ProductClient`), those clients are clones and won't prevent shutdown as long as the
95//! dependency graph is **acyclic**. Each actor shuts down when its own channel closes.
96//!
97//! **For cyclic dependencies**: Use an explicit `Shutdown` action instead of relying on
98//! channel closure. This ensures deterministic shutdown order regardless of dependency structure.
99//!
100//! ## Observability & Tracing
101//!
102//! The [`setup_tracing`] function initializes structured logging for the entire system.
103//!
104//! The framework uses the `tracing` crate with hierarchical spans to trace:
105//! - Actor lifecycle events (startup, shutdown)
106//! - Entity operations (Create, Get, Update, Delete, Actions)
107//! - Request flows with complete context
108//! - Errors with detailed entity IDs
109//!
110//! **Usage:**
111//! ```bash
112//! RUST_LOG=info cargo run # Compact logs
113//! RUST_LOG=debug cargo run # Full payloads
114//! ```
115//!
116//! 📖 **For complete tracing documentation**, see the [`tracing`] module with detailed
117//! examples, workflow traces, and best practices.
118//!
119//! ## Future Extensions
120//!
121//! As systems grow, this module may include:
122//!
123//! - Configuration management (loading from files/env)
124//! - Health checks and readiness probes
125//! - Metrics collection and export
126//! - Actor registry for dynamic discovery
127//! - Hot reload and zero-downtime updates
128
129pub mod order_system;
130
131pub use order_system::*;