37个版本
0.15.1 | 2024年7月9日 |
---|---|
0.15.0 | 2024年3月30日 |
0.14.3 | 2024年2月7日 |
0.14.2 | 2023年12月2日 |
0.4.1 | 2021年11月28日 |
#93 in 异步
7,489 每月下载量
用于 7 个crate(6个直接使用)
90KB
1.5K SLoC
tokio-graceful-shutdown
此crate提供了用于在tokio-rs基于的服务中执行优雅关闭的实用函数。
具体来说,它提供了
- 监听来自子系统的关闭请求
- 从子系统手动启动关闭
- 自动关闭
- SIGINT/SIGTERM/Ctrl+C
- 子系统故障
- 子系统panic
- 带有超时和错误传播的干净关闭流程
- 子系统嵌套
- 选择子系统树的局部关闭
使用示例
async fn subsys1(subsys: SubsystemHandle) -> Result<()>
{
log::info!("Subsystem1 started.");
subsys.on_shutdown_requested().await;
log::info!("Subsystem1 stopped.");
Ok(())
}
这显示了一个非常基本的异步子系统,它简单地启动,等待程序关闭被触发,然后停止自己。
现在可以像这样执行此子系统
#[tokio::main]
async fn main() -> Result<()> {
Toplevel::new(|s| async move {
s.start(SubsystemBuilder::new("Subsys1", subsys1))
})
.catch_signals()
.handle_shutdown_requests(Duration::from_millis(1000))
.await
.map_err(Into::into)
}
Toplevel
对象是子系统树的根对象。然后可以使用其 SubsystemHandle
对象的 start
方法在它中启动子系统。
catch_signals
方法使 Toplevel
对象监听 SIGINT/SIGTERM/Ctrl+C 并随后启动关闭。
handle_shutdown_requests
是 Toplevel
的最终且最重要的方法。它空闲直到程序进入关闭模式。然后,它收集所有子系统的返回值,确定全局错误状态并确保在指定的超时内完成关闭。最后,它返回一个错误值,可以直接用作 main
的返回代码。
更多示例可以在示例文件夹中查看。
构建
要在您的项目中使用此库,请进入项目目录并运行
cargo add tokio-graceful-shutdown
要运行其中一个示例(这里为01_normal_shutdown.rs
),只需克隆tokio-graceful-shutdown 仓库,进入仓库文件夹并执行
cargo run --example 01_normal_shutdown
动机
在异步程序上执行优雅的关闭是一个非平凡的问题。有几种解决方案,但它们都有各自的缺点
-
使用
tokio::select
进行全局取消。这是一个广泛使用的解决方案,但其缺点是取消的任务无法对其做出反应,因此它们无法优雅地关闭。 -
使用
tokio::spawn
进行分叉,并通过像tokio::CancellationToken
这样的机制来通知正在运行的任务需要关闭。这允许任务优雅地关闭,但需要大量的样板代码,例如- 将令牌传递给任务
- 等待任务完成
- 实现超时机制以防止挂起
- 收集子系统返回值
- 确保正确处理子系统错误
如果需要进一步的功能,例如监听信号如SIGINT或SIGTERM,样板代码会变得相当混乱。
这正是这个crate旨在提供的:对所有这些样板代码的整洁抽象。
贡献
欢迎贡献!
我主要编写这个crate是为了自己的方便,因此任何改进的想法都将非常受欢迎。
依赖
~4–13MB
~129K SLoC