Skip to content

Commit 199a641

Browse files
authored
feat: Add graceful shutdown (#396)
* feat: Add graceful shutdown * chore: Bump bytes crate to 1.11.1 Fixes RUSTSEC-2026-0007. * chore: Bump git2 crate to 0.20.4 Fixes RUSTSEC-2026-0008. * chore: Add changelog entry
1 parent ab14b18 commit 199a641

8 files changed

Lines changed: 87 additions & 63 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Changed
8+
9+
- Gracefully shutdown all concurrent tasks by forwarding the SIGTERM signal ([#396]).
10+
711
### Fixed
812

913
- BREAKING: Prevent Pod 0 restart by utilizing a mutating webhook.
@@ -13,6 +17,7 @@ All notable changes to this project will be documented in this file.
1317
env variable ([#387]).
1418

1519
[#387]: https://github.com/stackabletech/commons-operator/pull/387
20+
[#396]: https://github.com/stackabletech/commons-operator/pull/396
1621

1722
## [25.11.0] - 2025-11-07
1823

Cargo.lock

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

Cargo.nix

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ edition = "2021"
1010
repository = "https://github.com/stackabletech/commons-operator"
1111

1212
[workspace.dependencies]
13-
stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.101.1", features = ["telemetry", "webhook"] }
13+
stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.105.0", features = ["telemetry", "webhook"] }
1414

1515
anyhow = "1.0"
1616
built = { version = "0.8", features = ["chrono", "git2"] }

crate-hashes.json

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

rust/operator-binary/src/main.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use stackable_operator::{
1616
eos::EndOfSupportChecker,
1717
shared::yaml::SerializeOptions,
1818
telemetry::Tracing,
19+
utils::signal::SignalWatcher,
1920
};
2021
use webhook::create_webhook_server;
2122

@@ -90,9 +91,13 @@ async fn main() -> anyhow::Result<()> {
9091
description = built_info::PKG_DESCRIPTION
9192
);
9293

94+
// Watches for the SIGTERM signal and sends a signal to all receivers, which gracefully
95+
// shuts down all concurrent tasks below (EoS checker, controller).
96+
let sigterm_watcher = SignalWatcher::sigterm()?;
97+
9398
let eos_checker =
9499
EndOfSupportChecker::new(built_info::BUILT_TIME_UTC, maintenance.end_of_support)?
95-
.run()
100+
.run(sigterm_watcher.handle())
96101
.map(anyhow::Ok);
97102

98103
let client = stackable_operator::client::initialize_operator(
@@ -107,10 +112,13 @@ async fn main() -> anyhow::Result<()> {
107112
cm_store_tx,
108113
secret_store_tx,
109114
&watch_namespace,
115+
sigterm_watcher.handle(),
110116
)
111117
.map(anyhow::Ok);
118+
112119
let pod_restart_controller =
113-
restart_controller::pod::start(&client, &watch_namespace).map(anyhow::Ok);
120+
restart_controller::pod::start(&client, &watch_namespace, sigterm_watcher.handle())
121+
.map(anyhow::Ok);
114122

115123
let webhook_server = create_webhook_server(
116124
ctx,
@@ -119,8 +127,9 @@ async fn main() -> anyhow::Result<()> {
119127
client.as_kube_client(),
120128
)
121129
.await?;
130+
122131
let webhook_server = webhook_server
123-
.run()
132+
.run(sigterm_watcher.handle())
124133
.map_err(|err| anyhow!(err).context("failed to run webhook"));
125134

126135
futures::try_join!(

rust/operator-binary/src/restart_controller/pod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{sync::Arc, time::Duration};
1+
use std::{future::Future, sync::Arc, time::Duration};
22

33
use futures::StreamExt;
44
use http::StatusCode;
@@ -70,7 +70,10 @@ impl ReconcilerError for Error {
7070
}
7171
}
7272

73-
pub async fn start(client: &Client, watch_namespace: &WatchNamespace) {
73+
pub async fn start<F>(client: &Client, watch_namespace: &WatchNamespace, shutdown_signal: F)
74+
where
75+
F: Future<Output = ()> + Send + Sync + 'static,
76+
{
7477
let controller = Controller::new(
7578
watch_namespace.get_api::<PartialObjectMeta<Pod>>(client),
7679
// TODO: Can we only watch a subset of Pods with a specify label, e.g.
@@ -85,6 +88,7 @@ pub async fn start(client: &Client, watch_namespace: &WatchNamespace) {
8588
},
8689
));
8790
controller
91+
.graceful_shutdown_on(shutdown_signal)
8892
.run(
8993
reconcile,
9094
error_policy,

0 commit comments

Comments
 (0)