diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index fd385ff7b..3b74bcb75 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -4,6 +4,7 @@ pub mod certs; pub mod ip; #[cfg(feature = "net")] pub mod net; + #[cfg(feature = "net")] pub use net::*; @@ -53,6 +54,7 @@ pub use compress::*; #[cfg(feature = "notify")] mod notify; + #[cfg(feature = "sys")] pub mod sys; diff --git a/crates/utils/src/sys/user_agent.rs b/crates/utils/src/sys/user_agent.rs index 78360bfd2..8a1a0e0f0 100644 --- a/crates/utils/src/sys/user_agent.rs +++ b/crates/utils/src/sys/user_agent.rs @@ -140,12 +140,12 @@ pub fn get_user_agent(service: ServiceType) -> String { #[cfg(test)] mod tests { use super::*; - + use rustfs_config::VERSION; #[test] fn test_user_agent_format_basis() { let ua = get_user_agent(ServiceType::Basis); assert!(ua.starts_with("Mozilla/5.0")); - assert!(ua.contains("RustFS/1.0.0")); + assert!(ua.contains(&format!("RustFS/{}", VERSION).to_string())); println!("User-Agent: {}", ua); } @@ -153,7 +153,7 @@ mod tests { fn test_user_agent_format_core() { let ua = get_user_agent(ServiceType::Core); assert!(ua.starts_with("Mozilla/5.0")); - assert!(ua.contains("RustFS/1.0.0 (core)")); + assert!(ua.contains(&format!("RustFS/{} (core)", VERSION).to_string())); println!("User-Agent: {}", ua); } @@ -161,7 +161,7 @@ mod tests { fn test_user_agent_format_event() { let ua = get_user_agent(ServiceType::Event); assert!(ua.starts_with("Mozilla/5.0")); - assert!(ua.contains("RustFS/1.0.0 (event)")); + assert!(ua.contains(&format!("RustFS/{} (event)", VERSION).to_string())); println!("User-Agent: {}", ua); } @@ -169,7 +169,7 @@ mod tests { fn test_user_agent_format_logger() { let ua = get_user_agent(ServiceType::Logger); assert!(ua.starts_with("Mozilla/5.0")); - assert!(ua.contains("RustFS/1.0.0 (logger)")); + assert!(ua.contains(&format!("RustFS/{} (logger)", VERSION).to_string())); println!("User-Agent: {}", ua); } @@ -177,7 +177,7 @@ mod tests { fn test_user_agent_format_custom() { let ua = get_user_agent(ServiceType::Custom("monitor".to_string())); assert!(ua.starts_with("Mozilla/5.0")); - assert!(ua.contains("RustFS/1.0.0 (monitor)")); + assert!(ua.contains(&format!("RustFS/{} (monitor)", VERSION).to_string())); println!("User-Agent: {}", ua); } diff --git a/rustfs/src/main.rs b/rustfs/src/main.rs index 68f17cdfc..3e3bf234e 100644 --- a/rustfs/src/main.rs +++ b/rustfs/src/main.rs @@ -324,14 +324,6 @@ async fn run(opt: config::Opt) -> Result<()> { (sigterm_inner, sigint_inner) }; - #[cfg(not(unix))] - let (mut sigterm_inner, mut sigint_inner) = { - // Windows platform uses Ctrl+C as the only signal source - // Create two never-finished futures as placeholders - info!("Running on Windows, only Ctrl+C signal will be handled"); - (std::pin::pin!(std::future::pending::<()>()), std::pin::pin!(std::future::pending::<()>())) - }; - let hybrid_service = TowerToHyperService::new( tower::ServiceBuilder::new() .layer( @@ -392,38 +384,69 @@ async fn run(opt: config::Opt) -> Result<()> { loop { debug!("waiting for SIGINT or SIGTERM has_tls_certs: {}", has_tls_certs); // Wait for a connection - let (socket, _) = tokio::select! { - res = listener.accept() => { - match res { - Ok(conn) => conn, - Err(err) => { - error!("error accepting connection: {err}"); - continue; + // Wait for a connection + let (socket, _) = { + #[cfg(unix)] + { + tokio::select! { + res = listener.accept() => { + match res { + Ok(conn) => conn, + Err(err) => { + error!("error accepting connection: {err}"); + continue; + } + } + } + + _ = ctrl_c.as_mut() => { + info!("Ctrl-C received in worker thread"); + let _ = shutdown_tx_clone.send(()); + break; + } + + Some(_) = sigint_inner.recv() => { + info!("SIGINT received in worker thread"); + let _ = shutdown_tx_clone.send(()); + break; + } + + Some(_) = sigterm_inner.recv() => { + info!("SIGTERM received in worker thread"); + let _ = shutdown_tx_clone.send(()); + break; + } + + _ = shutdown_rx.recv() => { + info!("Shutdown signal received in worker thread"); + break; } } } + #[cfg(not(unix))] + { + tokio::select! { + res = listener.accept() => { + match res { + Ok(conn) => conn, + Err(err) => { + error!("error accepting connection: {err}"); + continue; + } + } + } - _ = ctrl_c.as_mut() => { - info!("Ctrl-C received in worker thread"); - let _ = shutdown_tx_clone.send(()); - break; - } + _ = ctrl_c.as_mut() => { + info!("Ctrl-C received in worker thread"); + let _ = shutdown_tx_clone.send(()); + break; + } - Some(_) = sigint_inner.recv() => { - info!("SIGINT received in worker thread"); - let _ = shutdown_tx_clone.send(()); - break; - } - - Some(_) = sigterm_inner.recv() => { - info!("SIGTERM received in worker thread"); - let _ = shutdown_tx_clone.send(()); - break; - } - - _ = shutdown_rx.recv() => { - info!("Shutdown signal received in worker thread"); - break; + _ = shutdown_rx.recv() => { + info!("Shutdown signal received in worker thread"); + break; + } + } } }; diff --git a/rustfs/src/server/service_state.rs b/rustfs/src/server/service_state.rs index d01093dbe..556458181 100644 --- a/rustfs/src/server/service_state.rs +++ b/rustfs/src/server/service_state.rs @@ -1,9 +1,7 @@ use atomic_enum::atomic_enum; -use std::sync::Arc; use std::sync::atomic::Ordering; +use std::sync::Arc; use std::time::Duration; -#[cfg(unix)] -use tokio::signal::unix::{SignalKind, signal}; use tracing::info; // a configurable shutdown timeout @@ -11,7 +9,7 @@ pub(crate) const SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(1); #[cfg(target_os = "linux")] fn notify_systemd(state: &str) { - use libsystemd::daemon::{NotifyState, notify}; + use libsystemd::daemon::{notify, NotifyState}; use tracing::{debug, error}; let notify_state = match state { "ready" => NotifyState::Ready, @@ -51,7 +49,9 @@ pub(crate) enum ServiceState { Stopped, } +#[cfg(unix)] pub(crate) async fn wait_for_shutdown() -> ShutdownSignal { + use tokio::signal::unix::{signal, SignalKind}; let mut sigterm = signal(SignalKind::terminate()).expect("failed to create SIGTERM signal handler"); let mut sigint = signal(SignalKind::interrupt()).expect("failed to create SIGINT signal handler"); @@ -71,6 +71,16 @@ pub(crate) async fn wait_for_shutdown() -> ShutdownSignal { } } +#[cfg(not(unix))] +pub(crate) async fn wait_for_shutdown() -> ShutdownSignal { + tokio::select! { + _ = tokio::signal::ctrl_c() => { + info!("Received Ctrl-C signal"); + ShutdownSignal::CtrlC + } + } +} + #[derive(Clone)] pub(crate) struct ServiceStateManager { state: Arc,