Skip to main content

flare_core_runtime/signal/
channel.rs

1//! 自定义通道信号实现
2
3use super::ShutdownSignal;
4use std::pin::Pin;
5use tokio::sync::oneshot;
6
7/// 自定义通道信号
8///
9/// 通过 oneshot 通道接收停机信号
10///
11/// # 示例
12///
13/// ```rust
14/// use flare_core_runtime::signal::ChannelSignal;
15/// use tokio::sync::oneshot;
16///
17/// let (tx, rx) = oneshot::channel();
18/// let signal = ChannelSignal::new("custom", rx);
19///
20/// // 发送停机信号
21/// tx.send(()).unwrap();
22/// ```
23pub struct ChannelSignal {
24    name: String,
25    rx: Option<oneshot::Receiver<()>>,
26}
27
28impl ChannelSignal {
29    /// 创建新的通道信号
30    ///
31    /// # 参数
32    ///
33    /// * `name` - 信号名称
34    /// * `rx` - oneshot 接收器
35    pub fn new(name: impl Into<String>, rx: oneshot::Receiver<()>) -> Self {
36        Self {
37            name: name.into(),
38            rx: Some(rx),
39        }
40    }
41}
42
43impl ShutdownSignal for ChannelSignal {
44    fn wait(&mut self) -> Pin<Box<dyn std::future::Future<Output = ()> + Send + '_>> {
45        if let Some(rx) = self.rx.take() {
46            Box::pin(async move {
47                let _ = rx.await;
48            })
49        } else {
50            // 如果已经被消费,直接等待
51            Box::pin(std::future::pending::<()>())
52        }
53    }
54
55    fn name(&self) -> &str {
56        &self.name
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[tokio::test]
65    async fn test_channel_signal() {
66        let (tx, rx) = oneshot::channel();
67        let mut signal = ChannelSignal::new("test", rx);
68
69        // 发送信号
70        tx.send(()).unwrap();
71
72        // 等待信号
73        signal.wait().await;
74    }
75
76    #[test]
77    fn test_channel_signal_name() {
78        let (_tx, rx) = oneshot::channel();
79        let signal = ChannelSignal::new("custom-signal", rx);
80        assert_eq!(signal.name(), "custom-signal");
81    }
82}