Skip to main content

yggdrasil/
shutdown.rs

1//! 进程退出协调。
2//!
3//! 收到 SIGTERM / Ctrl-C 后,Axum 的优雅关闭会等所有在途响应结束;SSE 这类
4//! 长连接永不自然结束,会把退出拖到容器的停止超时(podman 默认 10 秒)后被 SIGKILL。
5//! 长连接用 [`requested`] 在退出开始时主动收尾,startup 另用它限定排空时长。
6
7use std::sync::LazyLock;
8
9use tokio::sync::watch;
10
11static SHUTDOWN: LazyLock<watch::Sender<bool>> = LazyLock::new(|| watch::channel(false).0);
12
13/// 标记进程开始退出,唤醒所有 [`requested`] 等待者。
14pub fn trigger() {
15    SHUTDOWN.send_replace(true);
16}
17
18/// 进程开始退出时完成;已经开始退出则立即完成。
19pub async fn requested() {
20    let mut rx = SHUTDOWN.subscribe();
21    // Sender 是静态值,永不 drop,wait_for 不会返回 Err。
22    let _ = rx.wait_for(|stopping| *stopping).await;
23}