Skip to main content

flare_core_runtime/signal/
unix.rs

1//! Unix 信号实现 (SIGTERM/SIGINT)
2//!
3//! 仅在 Unix 平台上可用
4
5use super::ShutdownSignal;
6use std::pin::Pin;
7
8/// Unix 信号类型
9#[derive(Debug, Clone, Copy)]
10pub enum UnixSignalKind {
11    /// SIGTERM
12    Terminate,
13    /// SIGINT
14    Interrupt,
15}
16
17/// Unix 信号
18///
19/// 监听 SIGTERM 或 SIGINT 信号
20///
21/// # 示例
22///
23/// ```rust
24/// use flare_core_runtime::{UnixSignal, UnixSignalKind};
25///
26/// let signal = UnixSignal::new(UnixSignalKind::Terminate);
27/// ```
28#[cfg(target_family = "unix")]
29pub struct UnixSignal {
30    kind: UnixSignalKind,
31    name: String,
32}
33
34#[cfg(target_family = "unix")]
35impl UnixSignal {
36    /// 创建新的 Unix 信号
37    pub fn new(kind: UnixSignalKind) -> Self {
38        let name = match kind {
39            UnixSignalKind::Terminate => "sigterm",
40            UnixSignalKind::Interrupt => "sigint",
41        };
42        Self {
43            kind,
44            name: name.to_string(),
45        }
46    }
47}
48
49#[cfg(target_family = "unix")]
50impl ShutdownSignal for UnixSignal {
51    fn wait(&mut self) -> Pin<Box<dyn std::future::Future<Output = ()> + Send + '_>> {
52        use tokio::signal::unix::{SignalKind, signal};
53
54        let kind = match self.kind {
55            UnixSignalKind::Terminate => SignalKind::terminate(),
56            UnixSignalKind::Interrupt => SignalKind::interrupt(),
57        };
58
59        Box::pin(async move {
60            let mut signal = signal(kind).expect("Failed to register signal handler");
61            let _ = signal.recv().await;
62        })
63    }
64
65    fn name(&self) -> &str {
66        &self.name
67    }
68}
69
70#[cfg(not(target_family = "unix"))]
71pub struct UnixSignal {
72    _kind: UnixSignalKind,
73    name: String,
74}
75
76#[cfg(not(target_family = "unix"))]
77impl UnixSignal {
78    pub fn new(kind: UnixSignalKind) -> Self {
79        let name = match kind {
80            UnixSignalKind::Terminate => "sigterm",
81            UnixSignalKind::Interrupt => "sigint",
82        };
83        Self {
84            _kind: kind,
85            name: name.to_string(),
86        }
87    }
88}
89
90#[cfg(not(target_family = "unix"))]
91impl ShutdownSignal for UnixSignal {
92    fn wait(&mut self) -> Pin<Box<dyn std::future::Future<Output = ()> + Send + '_>> {
93        // 非 Unix 平台不支持,直接等待
94        Box::pin(std::future::pending::<()>())
95    }
96
97    fn name(&self) -> &str {
98        &self.name
99    }
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105
106    #[test]
107    fn test_unix_signal_new() {
108        let signal = UnixSignal::new(UnixSignalKind::Terminate);
109        assert_eq!(signal.name(), "sigterm");
110
111        let signal = UnixSignal::new(UnixSignalKind::Interrupt);
112        assert_eq!(signal.name(), "sigint");
113    }
114}