Skip to content

Commit b835194

Browse files
authored
chore(bin): handle sigkill,sigabrt,sighup (#3128)
## Linked Issues/PRs <!-- List of related issues/PRs --> ## Description <!-- List of detailed changes --> ## Checklist - [ ] Breaking changes are clearly marked as such in the PR description and changelog - [ ] New behavior is reflected in tests - [ ] [The specification](https://github.com/FuelLabs/fuel-specs/) matches the implemented behavior (link update PR if changes are needed) ### Before requesting review - [ ] I have reviewed the code myself - [ ] I have created follow-up issues caused by this PR and linked them here ### After merging, notify other teams [Add or remove entries as needed] - [ ] [Rust SDK](https://github.com/FuelLabs/fuels-rs/) - [ ] [Sway compiler](https://github.com/FuelLabs/sway/) - [ ] [Platform documentation](https://github.com/FuelLabs/devrel-requests/issues/new?assignees=&labels=new+request&projects=&template=NEW-REQUEST.yml&title=%5BRequest%5D%3A+) (for out-of-organization contributors, the person merging the PR will do this) - [ ] Someone else?
1 parent 9ceddcb commit b835194

File tree

4 files changed

+80
-14
lines changed

4 files changed

+80
-14
lines changed

.changes/fixed/3128.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Better signal handling (SIGABRT, SIGQUIT, SIGHUP).

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/fuel-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ hex = { workspace = true }
8686
hyper = { workspace = true }
8787
indicatif = { workspace = true, default-features = true }
8888
itertools = { workspace = true }
89+
libc = { version = "0.2.177" }
8990
mockall = { workspace = true, optional = true }
9091
num_cpus = { version = "1.16.0", optional = true }
9192
parking_lot = { workspace = true }

crates/fuel-core/src/lib.rs

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
#![deny(unused_crate_dependencies)]
44
#![deny(warnings)]
55

6+
use futures::{
7+
StreamExt,
8+
stream::FuturesUnordered,
9+
};
610
#[cfg(test)]
711
use tracing_subscriber as _;
812

@@ -63,27 +67,86 @@ pub struct ShutdownListener {
6367
pub token: CancellationToken,
6468
}
6569

70+
pub struct SignalKind {
71+
_inner: tokio::signal::unix::SignalKind,
72+
variant: SignalVariant,
73+
}
74+
75+
impl SignalKind {
76+
pub fn new(variant: SignalVariant) -> Self {
77+
let _inner = match variant {
78+
SignalVariant::SIGTERM => tokio::signal::unix::SignalKind::terminate(),
79+
SignalVariant::SIGINT => tokio::signal::unix::SignalKind::interrupt(),
80+
SignalVariant::SIGABRT => {
81+
tokio::signal::unix::SignalKind::from_raw(libc::SIGABRT)
82+
}
83+
SignalVariant::SIGHUP => tokio::signal::unix::SignalKind::hangup(),
84+
SignalVariant::SIGQUIT => tokio::signal::unix::SignalKind::quit(),
85+
};
86+
87+
Self { _inner, variant }
88+
}
89+
90+
pub fn decompose(self) -> (tokio::signal::unix::SignalKind, SignalVariant) {
91+
(self._inner, self.variant)
92+
}
93+
}
94+
95+
#[derive(Debug, Clone, Copy)]
96+
pub enum SignalVariant {
97+
SIGTERM,
98+
SIGINT,
99+
SIGABRT,
100+
SIGHUP,
101+
SIGQUIT,
102+
}
103+
66104
impl ShutdownListener {
67105
pub fn spawn() -> Self {
68106
let token = CancellationToken::new();
69107
{
70108
let token = token.clone();
71109
tokio::spawn(async move {
72-
let mut sigterm = tokio::signal::unix::signal(
73-
tokio::signal::unix::SignalKind::terminate(),
74-
)?;
75-
76-
let mut sigint = tokio::signal::unix::signal(
77-
tokio::signal::unix::SignalKind::interrupt(),
78-
)?;
79110
#[cfg(unix)]
80-
tokio::select! {
81-
_ = sigterm.recv() => {
82-
tracing::info!("Received SIGTERM");
83-
}
84-
_ = sigint.recv() => {
85-
tracing::info!("Received SIGINT");
86-
}
111+
{
112+
let signal_kinds: Vec<_> = vec![
113+
SignalVariant::SIGINT,
114+
SignalVariant::SIGTERM,
115+
SignalVariant::SIGABRT,
116+
SignalVariant::SIGHUP,
117+
SignalVariant::SIGQUIT,
118+
]
119+
.into_iter()
120+
.map(SignalKind::new)
121+
.collect();
122+
123+
let signals_with_variants: Vec<_> = signal_kinds
124+
.into_iter()
125+
.filter_map(|signal_kind| {
126+
let (signal_kind, variant) = signal_kind.decompose();
127+
match tokio::signal::unix::signal(signal_kind) {
128+
Ok(signal) => {
129+
tracing::info!("Registered signal handler for {variant:?}");
130+
Some((signal, variant))
131+
}
132+
Err(e) => {
133+
tracing::warn!("Failed to register signal handler for {variant:?}: {e}");
134+
None
135+
}
136+
}
137+
})
138+
.collect();
139+
140+
let mut signal_futs: FuturesUnordered<_> = signals_with_variants
141+
.into_iter()
142+
.map(|(mut signal, variant)| async move {
143+
signal.recv().await;
144+
variant
145+
})
146+
.collect();
147+
148+
let variant = signal_futs.next().await;
149+
tracing::error!("Received shutdown signal: {variant:?}");
87150
}
88151
#[cfg(not(unix))]
89152
{

0 commit comments

Comments
 (0)