Skip to main content

x_one/xserver/
blocking.rs

1//! 阻塞式服务器
2//!
3//! 用于 consumer/job 等服务,以阻塞方式启动,等待退出信号。
4
5use super::Server;
6use crate::error::XOneError;
7use tokio::sync::watch;
8
9/// 阻塞式服务器
10///
11/// 通过 watch channel 实现简单的阻塞等待,
12/// 调用 `stop()` 时触发 `run()` 返回。
13pub struct BlockingServer {
14    tx: watch::Sender<bool>,
15    rx: watch::Receiver<bool>,
16}
17
18impl BlockingServer {
19    /// 创建新的阻塞式服务器
20    pub fn new() -> Self {
21        let (tx, rx) = watch::channel(false);
22        Self { tx, rx }
23    }
24
25    /// 获取 receiver channel(仅测试用)
26    #[doc(hidden)]
27    pub fn rx(&self) -> watch::Receiver<bool> {
28        self.rx.clone()
29    }
30}
31
32impl Default for BlockingServer {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl Server for BlockingServer {
39    async fn run(&self) -> Result<(), XOneError> {
40        let mut rx = self.rx.clone();
41        // 等待 stop 信号
42        while !*rx.borrow() {
43            if rx.changed().await.is_err() {
44                break;
45            }
46        }
47        Ok(())
48    }
49
50    async fn stop(&self) -> Result<(), XOneError> {
51        let _ = self.tx.send(true);
52        Ok(())
53    }
54}