Skip to content

Commit d2df652

Browse files
author
Devdutt Shenoi
authored
refactor: use middlewares to reject requests when shutting down (#974)
1 parent 2cf490c commit d2df652

File tree

5 files changed

+27
-11
lines changed

5 files changed

+27
-11
lines changed

server/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ tower-http = { version = "0.6.1", features = ["cors"] }
2525

2626
### actix dependencies
2727
actix-web-httpauth = "0.8"
28-
actix-web = { version = "4.5.1", features = ["rustls-0_22"] }
28+
actix-web = { version = "4.9.0", features = ["rustls-0_22"] }
2929
actix-cors = "0.7.0"
3030
actix-web-prometheus = { version = "0.1" }
3131
actix-web-static-files = "4.0"

server/src/handlers/http/health_check.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
*/
1818

1919
use crate::option::CONFIG;
20+
use actix_web::body::MessageBody;
21+
use actix_web::dev::{ServiceRequest, ServiceResponse};
22+
use actix_web::error::ErrorServiceUnavailable;
2023
use actix_web::http::StatusCode;
21-
use actix_web::HttpResponse;
24+
use actix_web::middleware::Next;
25+
use actix_web::{Error, HttpResponse};
2226
use lazy_static::lazy_static;
2327
use std::sync::Arc;
2428
use tokio::signal::unix::{signal, SignalKind};
@@ -34,9 +38,21 @@ pub async fn liveness() -> HttpResponse {
3438
HttpResponse::new(StatusCode::OK)
3539
}
3640

37-
pub async fn handle_signals(shutdown_signal: Arc<Mutex<Option<oneshot::Sender<()>>>>) {
38-
let signal_received = SIGNAL_RECEIVED.clone();
41+
pub async fn check_shutdown_middleware(
42+
req: ServiceRequest,
43+
next: Next<impl MessageBody>,
44+
) -> Result<ServiceResponse<impl MessageBody>, Error> {
45+
// Acquire the shutdown flag to check if the server is shutting down.
46+
if *SIGNAL_RECEIVED.lock().await {
47+
// Return 503 Service Unavailable if the server is shutting down.
48+
Err(ErrorServiceUnavailable("Server is shutting down"))
49+
} else {
50+
// Continue processing the request if the server is not shutting down.
51+
next.call(req).await
52+
}
53+
}
3954

55+
pub async fn handle_signals(shutdown_signal: Arc<Mutex<Option<oneshot::Sender<()>>>>) {
4056
let mut sigterm =
4157
signal(SignalKind::terminate()).expect("Failed to set up SIGTERM signal handler");
4258
log::info!("Signal handler task started");
@@ -47,7 +63,7 @@ pub async fn handle_signals(shutdown_signal: Arc<Mutex<Option<oneshot::Sender<()
4763
log::info!("Received SIGTERM signal at Readiness Probe Handler");
4864

4965
// Set the shutdown flag to true
50-
let mut shutdown_flag = signal_received.lock().await;
66+
let mut shutdown_flag = SIGNAL_RECEIVED.lock().await;
5167
*shutdown_flag = true;
5268

5369
// Trigger graceful shutdown
@@ -77,12 +93,6 @@ pub async fn handle_signals(shutdown_signal: Arc<Mutex<Option<oneshot::Sender<()
7793
}
7894

7995
pub async fn readiness() -> HttpResponse {
80-
// Check if the application has received a shutdown signal
81-
let shutdown_flag = SIGNAL_RECEIVED.lock().await;
82-
if *shutdown_flag {
83-
return HttpResponse::new(StatusCode::SERVICE_UNAVAILABLE);
84-
}
85-
8696
// Check the object store connection
8797
if CONFIG.storage().get_object_store().check().await.is_ok() {
8898
HttpResponse::new(StatusCode::OK)

server/src/handlers/http/modal/ingest_server.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use crate::{
5454
option::CONFIG,
5555
};
5656
use actix_web::body::MessageBody;
57+
use actix_web::middleware::from_fn;
5758
use actix_web::web::resource;
5859
use actix_web::Scope;
5960
use actix_web::{web, App, HttpServer};
@@ -97,6 +98,7 @@ impl ParseableServer for IngestServer {
9798
App::new()
9899
.wrap(prometheus.clone())
99100
.configure(|config| IngestServer::configure_routes(config, None))
101+
.wrap(from_fn(health_check::check_shutdown_middleware))
100102
.wrap(actix_web::middleware::Logger::default())
101103
.wrap(actix_web::middleware::Compress::default())
102104
.wrap(cross_origin_config())

server/src/handlers/http/modal/query_server.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use crate::sync;
2929
use crate::users::dashboards::DASHBOARDS;
3030
use crate::users::filters::FILTERS;
3131
use crate::{analytics, banner, metrics, migration, rbac, storage};
32+
use actix_web::middleware::from_fn;
3233
use actix_web::web::{resource, ServiceConfig};
3334
use actix_web::{web, Scope};
3435
use actix_web::{App, HttpServer};
@@ -74,6 +75,7 @@ impl ParseableServer for QueryServer {
7475
App::new()
7576
.wrap(prometheus.clone())
7677
.configure(|config| QueryServer::configure_routes(config, oidc_client.clone()))
78+
.wrap(from_fn(health_check::check_shutdown_middleware))
7779
.wrap(actix_web::middleware::Logger::default())
7880
.wrap(actix_web::middleware::Compress::default())
7981
.wrap(cross_origin_config())

server/src/handlers/http/modal/server.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use crate::storage;
3838
use crate::sync;
3939
use crate::users::dashboards::DASHBOARDS;
4040
use crate::users::filters::FILTERS;
41+
use actix_web::middleware::from_fn;
4142
use std::sync::Arc;
4243
use tokio::sync::{oneshot, Mutex};
4344

@@ -89,6 +90,7 @@ impl ParseableServer for Server {
8990
App::new()
9091
.wrap(prometheus.clone())
9192
.configure(|cfg| Server::configure_routes(cfg, oidc_client.clone()))
93+
.wrap(from_fn(health_check::check_shutdown_middleware))
9294
.wrap(actix_web::middleware::Logger::default())
9395
.wrap(actix_web::middleware::Compress::default())
9496
.wrap(cross_origin_config())

0 commit comments

Comments
 (0)