counter/
counter.rs

1//! Counter Actor 示例
2//!
3//! 该示例展示了一个简单的计数器 Actor,演示以下功能:
4//! - Actor 状态管理
5//! - 异步处理消息
6//! - 指令的同步回传(oneshot channel)
7//! - 启动和结束 Actor
8use acty::{Actor, ActorExt, Inbox};
9use futures::StreamExt;
10use std::pin::pin;
11
12/// 计数器 Actor
13///
14/// 该 Actor 内部维护计数值 `value`,但结构体本身不包含字段。
15/// 状态在 `run` 方法中异步维护。
16struct Counter;
17
18/// Counter Actor 的消息类型
19///
20/// Actor 通过接收这些消息来更新或提供计数值。
21enum CounterMessage {
22    /// 增加计数值
23    Increment,
24
25    /// 请求获取当前计数值
26    ///
27    /// 发送方通过 `tokio::sync::oneshot::Receiver<u64>` 获取计数结果
28    GetValue(tokio::sync::oneshot::Sender<u64>),
29}
30
31/// 为 `Counter` Actor 实现 `Actor` trait
32///
33/// Actor 消息类型为 `CounterMessage`,内部异步维护计数值 `value`。
34///
35/// - 遍历 inbox 处理消息
36/// - 根据消息更新状态或通过 oneshot 返回结果
37impl Actor for Counter {
38    type Message = CounterMessage;
39
40    async fn run(self, inbox: impl Inbox<Item = Self::Message>) {
41        // 将 inbox 固定在栈上以便异步迭代
42        let mut inbox = pin!(inbox);
43
44        // 计数值
45        let mut value = 0;
46
47        // 异步处理每条消息
48        while let Some(msg) = inbox.next().await {
49            match msg {
50                // 增加计数
51                CounterMessage::Increment => value += 1,
52
53                // 通过 oneshot 返回当前计数
54                // 如果发送失败(例如 Actor 已结束),则忽略错误
55                CounterMessage::GetValue(tx) => tx.send(value).unwrap_or(()),
56            }
57        }
58    }
59}
60
61#[tokio::main]
62async fn main() {
63    // 启动计数器 Actor
64    let counter = Counter.start();
65
66    // 发送三次自增指令
67    counter.send(CounterMessage::Increment).unwrap_or(());
68    counter.send(CounterMessage::Increment).unwrap_or(());
69    counter.send(CounterMessage::Increment).unwrap_or(());
70
71    // 创建 oneshot 通道以获取当前计数值
72    let (rx, tx) = tokio::sync::oneshot::channel();
73    counter.send(CounterMessage::GetValue(rx)).unwrap_or(());
74
75    // 异步等待结果并打印
76    println!("count: {}", tx.await.unwrap());
77
78    // 解除 outbox 与 Actor 的绑定,确保 Actor 结束
79    counter.detach().await;
80}