Skip to content

Commit 71a446b

Browse files
authored
feat(stackable-webhook): Add shutdown signal handler (#767)
* feat(stackable-webhook): add shutdown signal handler * chore(stackable-webhook): update changelog * chore(stackable-webhook): update changelog with missing entry * fix(stackable-webhook): changelog link * docs(stackable-webhook): add explanation about the position of the healh route
1 parent 0e4076b commit 71a446b

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

crates/stackable-webhook/CHANGELOG.md

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

55
## [Unreleased]
66

7+
### Added
8+
9+
- Instrument `WebhookServer` with `AxumTraceLayer`, add static healthcheck without instrumentation ([#758]).
10+
- Add shutdown signal hander for the `WebhookServer` ([#767]).
11+
712
### Changed
813

914
- Bump kube to 0.89.0 and update all dependencies ([#762]).
1015

16+
[#758]: https://github.com/stackabletech/operator-rs/pull/758
1117
[#762]: https://github.com/stackabletech/operator-rs/pull/762
18+
[#767]: https://github.com/stackabletech/operator-rs/pull/767
1219

1320
## [0.2.0] - 2024-03-26
1421

crates/stackable-webhook/src/lib.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
//!
2525
//! [1]: crate::servers::ConversionWebhookServer
2626
use axum::{routing::get, Router};
27+
use futures_util::{pin_mut, select, FutureExt as _};
2728
use snafu::{ResultExt, Snafu};
2829
use stackable_telemetry::AxumTraceLayer;
30+
use tokio::signal::unix::{signal, SignalKind};
2931
use tower::ServiceBuilder;
3032
// use tower_http::trace::TraceLayer;
3133
use tracing::{debug, instrument};
@@ -131,10 +133,44 @@ impl WebhookServer {
131133
Self { options, router }
132134
}
133135

136+
/// Runs the Webhook server and sets up signal handlers for shutting down.
137+
///
138+
/// This does not implement graceful shutdown of the underlying server.
139+
pub async fn run(self) -> Result<()> {
140+
let future_server = self.run_server();
141+
let future_signal = async {
142+
let mut sigint = signal(SignalKind::interrupt()).expect("create SIGINT listener");
143+
let mut sigterm = signal(SignalKind::terminate()).expect("create SIGTERM listener");
144+
145+
debug!("created unix signal handlers");
146+
147+
select! {
148+
signal = sigint.recv().fuse() => {
149+
if signal.is_some() {
150+
debug!( "received SIGINT");
151+
}
152+
},
153+
signal = sigterm.recv().fuse() => {
154+
if signal.is_some() {
155+
debug!( "received SIGTERM");
156+
}
157+
},
158+
};
159+
};
160+
161+
// select requires Future + Unpin
162+
pin_mut!(future_server);
163+
pin_mut!(future_signal);
164+
165+
futures_util::future::select(future_server, future_signal).await;
166+
167+
Ok(())
168+
}
169+
134170
/// Runs the webhook server by creating a TCP listener and binding it to
135171
/// the specified socket address.
136172
#[instrument(name = "run_webhook_server", skip(self), fields(self.options))]
137-
pub async fn run(self) -> Result<()> {
173+
async fn run_server(self) -> Result<()> {
138174
debug!("run webhook server");
139175

140176
// Create an OpenTelemetry tracing layer
@@ -152,6 +188,7 @@ impl WebhookServer {
152188
let router = self
153189
.router
154190
.layer(service_builder)
191+
// The health route is below the AxumTraceLayer so as not to be instrumented
155192
.route("/health", get(|| async { "ok" }));
156193

157194
// Create server for TLS termination

0 commit comments

Comments
 (0)