30 个版本
0.4.1 | 2023 年 8 月 12 日 |
---|---|
0.3.17 |
|
0.3.16 | 2023 年 7 月 28 日 |
0.3.12 | 2023 年 1 月 22 日 |
0.3.11 | 2022 年 10 月 7 日 |
#1 in #erlang-otp
61 每月下载量
130KB
3K SLoC
agner — 进程 actors。
注意:目前这是一个研究项目,即 API 在 0.3.x 版本内可能发生不兼容的更改。
如前所述,agner 受 Erlang/OTP 启发,因此与实际框架的任何相似之处,无论是支持的还是已弃用的,都是纯粹故意的。 :)
actors
actor 是一个具有以下属性的活动
实现 Actor
actor 的行为由以下内容定义
- 其参数的类型;
- 它接受的消息的类型;
- 行为函数。
为了实现一个 actor,应该定义一个异步函数,该函数
- 返回一个具有
Into<Exit>
特性的值 - 并接受两个参数
- 对
Context<Message>
的可变引用; 参数
.
- 对
示例
use agner::actors::{Context, Exit, Never};
async fn shutdown_after_six_messages(context: &mut Context<String>, actor_name: String) {
for i in 0..6 {
let message = context.next_message().await;
eprintln!("Actor {:?} received {:?}", actor_name, message);
}
}
启动 Actor
actors 不能独立运行,它们需要一个 actor 系统 来启动。这是必要的,以避免仅仅使用库就强加全局状态。一个 System
是 actors 运行的范围。
示例
use agner::actors::{System, Context, Exit, Never};
async fn a_dummy(context: &mut Context<Option<String>>, actor_name: String) {
eprintln!("{}: hi!", actor_name);
while let Some(message) = context.next_message().await {
eprintln!("{}: received {:?}", actor_name, message);
}
eprintln!("{}: bye!", actor_name);
}
#[tokio::main]
async fn main() {
// create a system with default configuration
let system = System::new(Default::default());
let actor_id = system.spawn(
a_dummy,
"the-dummy".to_owned(),
Default::default())
.await.expect("Failed to spawn an actor");
system.send(actor_id, Some("one".to_owned())).await;
system.send(actor_id, Some("two".to_owned())).await;
system.send(actor_id, Some("three".to_owned())).await;
system.send(actor_id, Option::<String>::None).await;
let exit_reason = system.wait(actor_id).await;
eprintln!("{} exited: {:?}", actor_id, exit_reason);
}
终止 Actor
“故意”终止
从行为函数返回
如果行为函数返回,则行为者终止。行为函数的返回类型必须实现Into<Exit>
特质。
示例
use std::convert::Infallible;
use agner::actors::{Context, Exit};
async fn unit_is_normal_exit(_context: &mut Context<Infallible>, _args:()) {}
async fn result_into_exit(_context: &mut Context<Infallible>, _args:()) -> Result<(), Exit> {
Ok(()) // Equivalent to `Err(Exit::normal())`
}
调用 Context::exit
示例
use std::convert::Infallible;
use agner::actors::{Context, Exit};
async fn normal_exit(context: &mut Context<Infallible>, args: ()) -> Infallible {
context.exit(Exit::normal()).await;
unreachable!()
}
外部终止
行为者可以通过调用System::exit(&self, ActorID, Exit)
来终止。
在这种情况下,行为者会收到一个退出信号。如果行为者"捕获退出",它可以执行一个优雅的关闭(甚至继续运行)。也就是说,如果退出原因不是Exit::kill()
:在这种情况下,行为者将直接终止,其链接的行为者随后也会收到退出信号。
监督
由于整个项目都是基于Erlang/OTP,因此与OTP设计原则有一些(相当多的)相似之处,即
设计原则
启动和停止
TBD
统一监督器
TBD
混合监督器
TBD
内省
TBD
测试
TBD
依赖
~3–5.5MB
~93K SLoC