plugin: shutdown: add function that permit graceful shutdown by signal

Handling SIGTERM (etc) signals permit graceful shutdown, cleaning of resources etc.

Added in ipset and cluster.
This commit is contained in:
ppom 2026-02-12 12:00:00 +01:00
commit 3a61db9e6f
No known key found for this signature in database
4 changed files with 29 additions and 1 deletions

View file

@ -237,6 +237,8 @@ impl PluginInfo for Plugin {
}
async fn start(&mut self) -> RemoteResult<()> {
self.cluster_shutdown.delegate().handle_quit_signals()?;
let mut db = {
let path = PathBuf::from(".");
let (cancellation_token, task_tracker_token) = self.cluster_shutdown.token().split();

View file

@ -104,6 +104,8 @@ impl PluginInfo for Plugin {
}
async fn start(&mut self) -> RemoteResult<()> {
self.shutdown.delegate().handle_quit_signals()?;
let mut first_error = None;
for (i, set) in self.sets.iter().enumerate() {
// Retain if error

View file

@ -9,6 +9,6 @@ remoc.workspace = true
serde.workspace = true
serde_json.workspace = true
tokio.workspace = true
tokio.features = ["io-std"]
tokio.features = ["io-std", "signal"]
tokio-util.workspace = true
tokio-util.features = ["rt"]

View file

@ -36,7 +36,10 @@
//! }
//! }
//! ```
//!
//! [`ShutdownDelegate::handle_quit_signals`] permits to handle SIGHUP, SIGINT and SIGTERM by gracefully shutting down tasks.
use tokio::signal::unix::{SignalKind, signal};
use tokio_util::{
sync::{CancellationToken, WaitForCancellationFuture},
task::task_tracker::{TaskTracker, TaskTrackerToken},
@ -94,6 +97,27 @@ impl ShutdownDelegate {
pub fn ask_shutdown(&self) {
self.0.cancel();
}
/// Ensure [`Self::ask_shutdown`] is called whenever we receive SIGHUP,
/// SIGTERM or SIGINT. Spawns a task that consumes self.
pub fn handle_quit_signals(self) -> Result<(), String> {
let err_str = |err| format!("could not register signal: {err}");
let mut sighup = signal(SignalKind::hangup()).map_err(err_str)?;
let mut sigint = signal(SignalKind::interrupt()).map_err(err_str)?;
let mut sigterm = signal(SignalKind::terminate()).map_err(err_str)?;
tokio::spawn(async move {
let signal = tokio::select! {
_ = sighup.recv() => "SIGHUP",
_ = sigint.recv() => "SIGINT",
_ = sigterm.recv() => "SIGTERM",
};
eprintln!("received {signal}, closing...");
self.ask_shutdown();
});
Ok(())
}
}
/// Created by a [`ShutdownController`].