theta 0.1.0-alpha.56

An Rust Actor Framework
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
use std::{
    fmt::Debug,
    future::{self, Future},
    panic::UnwindSafe,
};

use crate::{
    context::Context,
    message::{Continuation, Escalation, Signal},
};
#[cfg(feature = "remote")]
use {
    crate::remote::{base::ActorTypeId, serde::FromTaggedBytes},
    serde::{Deserialize, Serialize},
};

/// Core trait that defines actor behavior.
///
/// This trait must be implemented by all actor types. It defines the message type,
/// state updateing type, and behavior methods for message processing and supervision.
///
/// # Usage with `#[actor]` Macro
///
/// Actors are typically implemented using the `#[actor]` attribute macro which
/// generates the necessary boilerplate. The macro provides significant conveniences
/// and automatic implementations.
///
/// ## Behavior Specification Syntax
///
/// The `#[actor]` macro allows you to specify actor behavior using a special syntax
/// within the `const _: () = {}` block. Inside this block:
///
/// - `&mut self` - Reference to the actor instance (automatically provided)
/// - `ctx` - The actor's context for communication and spawning (automatically provided)
/// - Message handlers use async closure syntax with pattern destructuring
/// - Optional return types for ask/forward patterns
///
/// ### Message Handler Patterns
///
/// ```
/// # use theta::prelude::*;
/// # use serde::{Serialize, Deserialize};
/// # #[derive(Debug, Clone, ActorArgs)]
/// # struct MyActor;
/// # #[derive(Debug, Clone, Serialize, Deserialize)]
/// # struct DataMessage { data: i32 }
/// # #[derive(Debug, Clone, Serialize, Deserialize)]
/// # struct FieldMessage { field: i32 }
/// # #[derive(Debug, Clone, Serialize, Deserialize)]
/// # struct Response;
/// # #[derive(Debug, Clone, Serialize, Deserialize)]
/// # struct SimpleMessage;
/// # #[actor("12345678-1234-5678-9abc-123456789abc")]
/// # impl Actor for MyActor {
/// #     const _: () = {
/// async |data: DataMessage| { /* ... */ };                                    // Fire-and-forget (tell)
/// async |FieldMessage { field }: FieldMessage| -> Response { Response };     // Request-response (ask)
/// async |_: SimpleMessage| { /* ... */ };                                     // Ignore message data
/// #     };
/// # }
/// ```
///
/// ## Basic Example
///
/// ```
/// use theta::prelude::*;
/// use serde::{Serialize, Deserialize};
///
/// #[derive(Debug, Clone, ActorArgs)]
/// struct Counter { value: i64 }
///
/// #[derive(Debug, Clone, Serialize, Deserialize)]
/// struct Increment(i64);
///
/// #[derive(Debug, Clone, Serialize, Deserialize)]
/// struct GetValue;
///
/// #[actor("12345678-1234-5678-9abc-123456789abc")]
/// impl Actor for Counter {
///     const _: () = {
///         // Basic message handler
///         async |Increment(amount): Increment| {
///             self.value += amount;
///         };
///
///         // Return type for ask pattern
///         async |GetValue: GetValue| -> i64 {
///             self.value
///         };
///     };
/// }
/// ```
///
/// ## Default Implementations Provided by Macro
///
/// The `#[actor]` macro automatically provides:
/// - `type View = Nil;` (unless you specify a custom type)
/// - Empty message handler block if no handlers are specified
/// - Message enum generation and dispatch logic
/// - Remote communication support when the `remote` feature is enabled
/// - **Auto-generated `hash_code`**: When you define a manual `type View` without providing
///   a manual `hash_code` implementation, the macro automatically generates one using
///   `AHasher`.
///
/// ## Advanced Usage
///
/// You can customize state updateing and use context for child actor management:
///
/// ```
/// use theta::prelude::*;
/// use serde::{Serialize, Deserialize};
///
/// #[derive(Debug, Clone, Hash, ActorArgs)]
/// struct Supervisor {
///     worker_count: u32,
/// }
///
/// #[derive(Debug, Clone, Serialize, Deserialize)]
/// struct SpawnWorker;
///
/// #[derive(Debug, Clone, Serialize, Deserialize)]
/// struct WorkerStats {
///     worker_count: u32,
/// }
///
/// impl From<&Supervisor> for WorkerStats {
///     fn from(supervisor: &Supervisor) -> Self {
///         WorkerStats {
///             worker_count: supervisor.worker_count,
///         }
///     }
/// }
///
/// #[actor("87654321-4321-8765-dcba-987654321fed")]
/// impl Actor for Supervisor {
///     type View = WorkerStats;
///
///     const _: () = {
///         async |SpawnWorker: SpawnWorker| {
///             self.worker_count += 1;
///         };
///     };
/// }
/// ```
///
/// ## What's Automatically Available in Message Handlers
///
/// Within each message handler closure, you have automatic access to:
/// - `&mut self` - Mutable reference to the actor instance for state modification
/// - `ctx: Context<Self>` - Actor context providing:
///   - **Self-messaging**: `ctx.this.upgrade()` to get a reference to send messages to itself
///   - **Child spawning**: `ctx.spawn()` to create child actors
///   - **Actor metadata**: `ctx.id()` to get the actor's unique identifier
///   - **Lifecycle control**: `ctx.terminate()` to stop the actor
///
/// ### Key Context Usage Patterns
///
/// ```
/// # use theta::prelude::*;
/// # use serde::{Serialize, Deserialize};
/// # #[derive(Debug, Clone, ActorArgs)]
/// # struct MyActor;
/// # #[derive(Debug, Clone, Serialize, Deserialize)]
/// # struct SomeMessage;
/// # #[actor("12345678-1234-5678-9abc-123456789abc")]
/// # impl Actor for MyActor {
/// #     const _: () = {
/// #         async |SomeMessage: SomeMessage| {
/// // Send message to self (most common pattern)
/// if let Some(self_ref) = ctx.this.upgrade() {
///     let _ = self_ref.tell(SomeMessage);
/// }
///
/// // Get actor ID for logging/debugging
/// println!("Actor {} processing message", ctx.id());
/// #         };
/// #     };
/// # }
/// ```
///
/// These are provided transparently by the macro, so you can use them freely
/// without explicit parameter declarations.
pub trait Actor: Sized + Debug + Send + UnwindSafe + 'static {
    /// The message type this actor can receive.
    ///
    /// For local-only actors, this can be any `Send` type.
    /// For remote-capable actors (with `remote` feature), messages must also
    /// implement `Serialize`, `Deserialize`, and `FromTaggedBytes`.
    #[cfg(not(feature = "remote"))]
    type Msg: Debug + Send;

    #[cfg(feature = "remote")]
    type Msg: Debug + Send + Serialize + for<'de> Deserialize<'de> + FromTaggedBytes;

    /// Type used for updateing actor state to monitors.
    ///
    /// This type represents a snapshot of the actor's state that can be
    /// sent to monitors. It must implement `From<&Self>` to convert from
    /// the actor's current state.
    #[cfg(not(feature = "remote"))]
    type View: Debug + Send + UnwindSafe + Clone + for<'a> From<&'a Self> + 'static;

    #[cfg(feature = "remote")]
    type View: Debug
        + Send
        + UnwindSafe
        + Clone
        + for<'a> From<&'a Self>
        + Serialize
        + for<'de> Deserialize<'de>;

    /// Process incoming messages.
    ///
    /// This method is called for each message received by the actor.
    /// It is panic-safe - panics will be caught and escalated to the supervisor.
    ///
    /// **Note:** This method is typically generated by the `#[actor]` macro
    /// and should not be implemented manually.
    ///
    /// # Arguments
    ///
    /// * `ctx` - The actor's context for communication
    /// * `msg` - The incoming message to process
    /// * `k` - Continuation for handling responses
    #[allow(unused_variables)]
    fn process_msg(
        &mut self,
        ctx: &Context<Self>,
        msg: Self::Msg,
        k: Continuation,
    ) -> impl Future<Output = ()> + Send;

    /// Handle escalations from child actors.
    ///
    /// This method is called when a child actor fails and needs supervision.
    /// The default implementation restarts the child actor.
    ///
    /// # Arguments
    ///
    /// * `escalation` - Information about the child actor failure
    ///
    /// # Return
    ///
    /// A tuple of signals: (`signal_to_child`, `signal_to_parent`)
    #[allow(unused_variables)]
    fn supervise(
        &mut self,
        escalation: Escalation,
    ) -> impl Future<Output = (Signal, Option<Signal>)> + Send {
        __default_supervise(self, escalation)
    }

    /// Called when the actor is restarted.
    ///
    /// This lifecycle hook is invoked before re-initialization during a restart.
    /// The default implementation does nothing.
    ///
    /// **Note:** This method is panic-safe, but panics will be logged rather than escalated.
    /// State corruption is possible if this method panics.
    #[allow(unused_variables)]
    fn on_restart(&mut self) -> impl Future<Output = ()> + Send {
        __default_on_restart(self)
    }

    /// Called when the actor is terminating or being dropped.
    ///
    /// This lifecycle hook allows for cleanup operations before the actor shuts down.
    /// The default implementation does nothing.
    ///
    /// **Note:** This method is panic-safe, but panics will be logged rather than escalated.
    /// Since the message loop has stopped, any messages sent to `self` will be lost.
    ///
    /// # Arguments
    ///
    /// * `exit_code` - The reason for termination
    #[allow(unused_variables)]
    fn on_exit(&mut self, exit_code: ExitCode) -> impl Future<Output = ()> + Send {
        __default_on_exit(self, exit_code)
    }

    /// Generate a hash code for this actor instance.
    ///
    /// This method is used to determine whether the actor sends state update to monitors.
    /// The default implementation returns a constant value.
    ///
    /// ## Automatic Generation
    ///
    /// When using the `#[actor]` macro, if you:
    /// 1. Define a custom `type View`
    /// 2. Don't provide a custom `hash_code` implementation
    ///
    /// Then the macro will automatically generate a `hash_code` implementation
    /// that uses `AHasher` assuming `self` is `Hash`.
    ///
    /// ```
    /// # use theta::prelude::*;
    /// # use serde::{Serialize, Deserialize};
    /// # #[derive(Debug, Clone, Hash, ActorArgs)]
    /// # struct MyActor { value: i32 }
    /// # #[derive(Debug, Clone, Serialize, Deserialize, Hash)]
    /// # struct MyView { value: i32 }
    /// # impl From<&MyActor> for MyView {
    /// #     fn from(a: &MyActor) -> Self { MyView { value: a.value } }
    /// # }
    /// // This will auto-generate hash_code using AHasher
    /// #[actor("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee")]
    /// impl Actor for MyActor {
    ///     type View = MyView; // Custom View type that implements Hash
    ///     // No hash_code implementation provided
    /// }
    /// ```
    ///
    /// The auto-generated implementation is equivalent to:
    /// ```
    /// # use theta::prelude::*;
    /// # use serde::{Serialize, Deserialize};
    /// # use std::hash::{Hash, Hasher};
    /// # use theta::__private::ahash::AHasher;
    /// # #[derive(Debug, Clone, Hash, ActorArgs)]
    /// # struct MyActor { value: i32 }
    /// # #[derive(Debug, Clone, Serialize, Deserialize, Hash)]
    /// # struct MyView { value: i32 }
    /// # impl From<&MyActor> for MyView {
    /// #     fn from(a: &MyActor) -> Self { MyView { value: a.value } }
    /// # }
    /// # #[actor("aaaaaaaa-bbbb-cccc-dddd-ffffffffffff")]
    /// # impl Actor for MyActor {
    /// #     type View = MyView;
    /// fn hash_code(&self) -> u64 {
    ///     let mut hasher = AHasher::default();
    ///     Hash::hash(&self.state_view(), &mut hasher);
    ///     hasher.finish()
    /// }
    /// # }
    /// ```
    #[allow(unused_variables)]
    fn hash_code(&self) -> u64 {
        0
    }

    /// Generate a state view for monitoring.
    ///
    /// This method creates a snapshot of the actor's current state for monitors.
    /// The default implementation uses the `From<&Self>` conversion.
    #[allow(unused_variables)]
    fn state_view(&self) -> Self::View {
        self.into()
    }

    /// Internal implementation ID for remote actors.
    ///
    /// **Note:** This should not be implemented manually - it's generated by the `#[actor]` macro.
    #[cfg(feature = "remote")]
    const IMPL_ID: ActorTypeId;
}

/// Trait for actor initialization arguments.
///
/// This trait defines how actors are initialized from their arguments.
/// In case of actor it self is args and `Clone`, could be derived using `#[derive(ActorArgs)]`.
///
/// # Example
///
/// #[cfg(feature = "full")]
/// ```
/// use theta::prelude::*;
/// use serde::{Serialize, Deserialize};
///
/// #[derive(Debug, Clone, ActorArgs)]
/// struct MyActor {
///     name: String,
///     value: i32,
/// }
///
/// #[derive(Debug, Clone, Serialize, Deserialize)]
/// struct Increment(i32);
///
/// #[actor("12345678-1234-5678-9abc-123456789abc")]
/// impl Actor for MyActor {
///     const _: () = {
///         async |Increment(amount): Increment| {
///             self.value += amount;
///         };
///     };
/// }
/// ```
pub trait ActorArgs: Clone + Send + UnwindSafe + 'static {
    type Actor: Actor;

    /// Initialize an actor from the given arguments.
    ///
    /// This method is called when spawning a new actor and should return
    /// the initialized actor state. The method is panic-safe - any panics
    /// will be caught and escalated to the supervisor.
    ///
    /// # Arguments
    ///
    /// * `ctx` - The actor's context for communication and spawning children
    /// * `args` - The initialization arguments
    fn initialize(
        ctx: Context<Self::Actor>,
        args: &Self,
    ) -> impl Future<Output = Self::Actor> + Send + UnwindSafe;
}

/// Unique identifier for each actor instance.
pub type ActorId = uuid::Uuid;

/// Reason for actor termination.
#[derive(Debug, Clone)]
pub enum ExitCode {
    /// Actor was dropped normally
    Dropped,
    /// Actor was explicitly terminated
    Terminated,
}

/// Default supervision strategy that terminates failing actors.
///
/// # Arguments
///
/// * `_actor` - The actor being supervised (unused in default implementation)
/// * `_escalation` - The escalation information (unused in default implementation)
///
/// # Return
///
/// `(Signal, Option<Signal>)` - Signal for the failing actor and optional parent signal
pub fn __default_supervise<A: Actor>(
    _actor: &mut A,
    _escalation: Escalation,
) -> impl Future<Output = (Signal, Option<Signal>)> + Send {
    future::ready((Signal::Terminate, None))
}

/// Default restart handler that performs no additional actions.
///
/// # Arguments
///
/// * `_actor` - The actor being restarted (unused in default implementation)
pub fn __default_on_restart<A: Actor>(_actor: &mut A) -> impl Future<Output = ()> + Send {
    future::ready(())
}

/// Default exit handler that performs no additional actions.
///
/// # Arguments
///
/// * `_actor` - The actor exiting (unused in default implementation)
/// * `_exit_code` - The exit code (unused in default implementation)
pub fn __default_on_exit<A: Actor>(
    _actor: &mut A,
    _exit_code: ExitCode,
) -> impl Future<Output = ()> + Send {
    future::ready(())
}