From 17296cdcb85bde4cad468dc662fde2fd8d70961b Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Fri, 19 Jan 2024 15:18:55 +0000 Subject: [PATCH] fix: [#626] healt check api server shutdown This fixes: - The error: "Failed to install stop signal: channel closed" - And CRTL+C to shutdown the service --- src/bootstrap/jobs/health_check_api.rs | 20 +++++++++++++------ src/servers/health_check_api/server.rs | 5 ++++- tests/servers/health_check_api/environment.rs | 10 ++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/jobs/health_check_api.rs b/src/bootstrap/jobs/health_check_api.rs index 7eeafe97b..e57d1c151 100644 --- a/src/bootstrap/jobs/health_check_api.rs +++ b/src/bootstrap/jobs/health_check_api.rs @@ -42,24 +42,32 @@ pub async fn start_job(config: &HealthCheckApi, register: ServiceRegistry) -> Jo let (tx_start, rx_start) = oneshot::channel::(); let (tx_halt, rx_halt) = tokio::sync::oneshot::channel::(); - drop(tx_halt); + + let protocol = "http"; // Run the API server let join_handle = tokio::spawn(async move { - info!(target: "Health Check API", "Starting on: http://{}", bind_addr); + info!(target: "Health Check API", "Starting on: {protocol}://{}", bind_addr); let handle = server::start(bind_addr, tx_start, rx_halt, register); if let Ok(()) = handle.await { - info!(target: "Health Check API", "Stopped server running on: http://{}", bind_addr); + info!(target: "Health Check API", "Stopped server running on: {protocol}://{}", bind_addr); } }); - // Wait until the API server job is running + // Wait until the server sends the started message match rx_start.await { - Ok(msg) => info!(target: "Health Check API", "Started on: http://{}", msg.address), + Ok(msg) => info!(target: "Health Check API", "Started on: {protocol}://{}", msg.address), Err(e) => panic!("the Health Check API server was dropped: {e}"), } - join_handle + // Wait until the server finishes + tokio::spawn(async move { + assert!(!tx_halt.is_closed(), "Halt channel for Health Check API should be open"); + + join_handle + .await + .expect("it should be able to join to the Health Check API server task"); + }) } diff --git a/src/servers/health_check_api/server.rs b/src/servers/health_check_api/server.rs index ecc6fe427..8ba20691f 100644 --- a/src/servers/health_check_api/server.rs +++ b/src/servers/health_check_api/server.rs @@ -8,6 +8,7 @@ use axum::routing::get; use axum::{Json, Router}; use axum_server::Handle; use futures::Future; +use log::debug; use serde_json::json; use tokio::sync::oneshot::{Receiver, Sender}; @@ -37,10 +38,12 @@ pub fn start( let handle = Handle::new(); + debug!(target: "Health Check API", "Starting service with graceful shutdown in a spawned task ..."); + tokio::task::spawn(graceful_shutdown( handle.clone(), rx_halt, - format!("shutting down http server on socket address: {address}"), + format!("Shutting down http server on socket address: {address}"), )); let running = axum_server::from_tcp(socket) diff --git a/tests/servers/health_check_api/environment.rs b/tests/servers/health_check_api/environment.rs index 9aa3ab16d..c98784282 100644 --- a/tests/servers/health_check_api/environment.rs +++ b/tests/servers/health_check_api/environment.rs @@ -1,6 +1,7 @@ use std::net::SocketAddr; use std::sync::Arc; +use log::debug; use tokio::sync::oneshot::{self, Sender}; use tokio::task::JoinHandle; use torrust_tracker::bootstrap::jobs::Started; @@ -50,13 +51,22 @@ impl Environment { let register = self.registar.entries(); + debug!(target: "Health Check API", "Spawning task to launch the service ..."); + let server = tokio::spawn(async move { + debug!(target: "Health Check API", "Starting the server in a spawned task ..."); + server::start(self.state.bind_to, tx_start, rx_halt, register) .await .expect("it should start the health check service"); + + debug!(target: "Health Check API", "Server started. Sending the binding {} ...", self.state.bind_to); + self.state.bind_to }); + debug!(target: "Health Check API", "Waiting for spawning task to send the binding ..."); + let binding = rx_start.await.expect("it should send service binding").address; Environment {