3 个版本
0.1.2 | 2024 年 4 月 9 日 |
---|---|
0.1.1 | 2024 年 4 月 9 日 |
0.1.0 | 2024 年 4 月 9 日 |
#605 在 数据结构
2MB
525 行
supertrees – Rust 监督树
一个实验性的 Rust 包,以 Erlang/OTP 为灵感实现监督树。
有关详细信息,请参阅文档。
lib.rs
:
基于异步 Rust 的监督树,灵感来自 Erlang/OTP
此包为异步 Rust 提供了基于 Erlang/OTP 的监督树实现。它提供了一个可用于创建监督树的 Supertree
结构体,以及一个可以被添加到监督树中的工作器实现的 Worker
特性。
此包旨在与异步 Rust 和 Tokio 运行时一起使用,但理论上也可以与其他异步运行时一起使用。
在当前状态下,此包被视为实验性的,不应用于生产服务,除非您非常热衷于这个想法,并愿意为此包的开发做出贡献。值得注意的是,此包缺乏许多 Erlang/OTP 中的功能,例如监视、跟踪和分布式消息传递,尽管 Tokio 提供了可以与此包一起使用的跟踪和指标系统(尚未经过测试)。
有关详细示例,请参阅tests
目录中的集成测试。
功能
- 监督树:使用根监督器创建监督树
- 工作器:将工作器添加到监督树
- 异步工作器:工作器是异步的,可以使用 async/await 语法
- 进程隔离:通过进程分叉构建树,提供额外的隔离(目前未实现 IPC)
- 分层结构:创建工作器和监督器的层次结构
- 重启策略:为工作器定义重启策略
- 退避策略:为工作器定义退避策略
与 Erlang/OTP 的比较
- 与 Erlang/OTP 不同,此包不提供分布式消息传递。另一个可供参考的包是 genserver,但它不提供 IPC。
- 此包不提供监视或跟踪,但 Tokio 本身包含一个跟踪和指标系统,可以与此包一起使用。
- Erlang/OTP 使用抢占式绿色线程调度器,而此crate使用Tokio运行时,这是一个协作式多任务运行时。
- 树中的每个单独的监督者都是一个单独的线程,它们之间没有共享内存或IPC(尚未实现,欢迎提交PR)。这与Erlang/OTP使用的无共享架构形成对比。
- Erlang/OTP经过实战检验,已在生产中使用数十年,而此crate尚未。
示例
使用此crate创建一个包含根监督者、两个子监督者和三个工作者的监督树的基本示例
use supertrees::{Restartable, Supertree, Worker};
#[derive(Debug)]
struct MyWorker {
num: i32,
}
impl MyWorker {
fn new(num: i32) -> Self {
Self { num }
}
}
impl Worker for MyWorker {
// init() is called before the worker is started, and will be called
// after each subsequent restart, so it should be safe to call this
// repeatedly and any state that needs to be reset should be reset here.
fn init(
&self,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = ()> + Send + 'static>> {
let num = self.num;
Box::pin(async move {
println!("hi, I'm worker num={num} :)");
})
}
}
// We must provide a restart and backoff policy for the worker, but we can
// use the default policies.
impl Restartable for MyWorker {}
let root = Supertree::new()
.add_worker(MyWorker::new(1))
.add_supervisor(|s| {
s.add_worker(MyWorker::new(2))
.add_supervisor(|s| s.add_worker(MyWorker::new(3)))
});
dbg!(&root);
// Now you can start the supervision tree, which will run forever.
// Uncomment the line below to run the supervision tree.
// root.start();