@@ -231,10 +231,16 @@ fn main() -> anyhow::Result<()> {
231231 println ! ( "Built with ❤️ in Rust" ) ;
232232 }
233233
234- Commands :: Service { action : _action } => {
234+ Commands :: Service { action } => {
235+ #[ cfg( not( target_os = "linux" ) ) ]
236+ {
237+ let _ = action;
238+ eprintln ! ( "❌ Service management is only supported on Linux." ) ;
239+ }
240+
235241 #[ cfg( target_os = "linux" ) ]
236242 {
237- let cmd = match _action {
243+ let cmd = match action {
238244 ServiceAction :: Start => "start" ,
239245 ServiceAction :: Stop => "stop" ,
240246 ServiceAction :: Restart => "restart" ,
@@ -250,7 +256,7 @@ fn main() -> anyhow::Result<()> {
250256
251257 match status {
252258 Ok ( s) if s. success ( ) => {
253- let past_tense = match _action {
259+ let past_tense = match action {
254260 ServiceAction :: Start => "started" ,
255261 ServiceAction :: Stop => "stopped" ,
256262 ServiceAction :: Restart => "restarted" ,
@@ -279,7 +285,22 @@ fn main() -> anyhow::Result<()> {
279285 Ok ( ( ) )
280286}
281287
282- fn run_server ( _config_path : String , config : pingclair_core:: config:: PingclairConfig ) {
288+ fn run_server ( config_path : String , config : pingclair_core:: config:: PingclairConfig ) {
289+ #[ cfg( not( target_os = "linux" ) ) ]
290+ let _ = config_path;
291+
292+ // Create a background Tokio runtime for async tasks (HTTP/3, SIGHUP, etc.)
293+ // We do this in a separate thread to avoid conflicts with Pingora's runtime.
294+ let bg_runtime = tokio:: runtime:: Runtime :: new ( ) . expect ( "Failed to create background runtime" ) ;
295+ let bg_handle = bg_runtime. handle ( ) . clone ( ) ;
296+
297+ std:: thread:: spawn ( move || {
298+ bg_runtime. block_on ( async {
299+ // Keep the runtime alive
300+ std:: future:: pending :: < ( ) > ( ) . await ;
301+ } ) ;
302+ } ) ;
303+
283304 if config. servers . is_empty ( ) {
284305 tracing:: warn!( "⚠️ No servers configured!" ) ;
285306 return ;
@@ -345,7 +366,7 @@ fn run_server(_config_path: String, config: pingclair_core::config::PingclairCon
345366 let port_proxies = port_proxies. clone ( ) ;
346367 let addr_str = _addr. clone ( ) ;
347368
348- tokio :: spawn ( async move {
369+ bg_handle . spawn ( async move {
349370 let mut quic_config = pingclair_proxy:: quic:: QuicConfig :: default ( ) ;
350371 quic_config. listen = socket_addr;
351372
@@ -387,11 +408,11 @@ fn run_server(_config_path: String, config: pingclair_core::config::PingclairCon
387408 // 🔔 Signal Handling for SIGHUP (Reload)
388409 // ========================================
389410 #[ cfg( target_os = "linux" ) ]
390- if !_config_path . is_empty ( ) {
391- let config_path = _config_path . clone ( ) ;
411+ if !config_path . is_empty ( ) {
412+ let config_path = config_path . clone ( ) ;
392413 let port_proxies = port_proxies. clone ( ) ;
393414
394- tokio :: spawn ( async move {
415+ bg_handle . spawn ( async move {
395416 use tokio:: signal:: unix:: { signal, SignalKind } ;
396417
397418 let mut stream = match signal ( SignalKind :: hangup ( ) ) {
0 commit comments