Skip to content

Commit 4f55f91

Browse files
authored
feat(hyper): propagate connection errors during graceful shutdown and app lifecycle (#261)
1 parent 0e651bf commit 4f55f91

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

crates/hyper/src/lib.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use hyper_util::rt::TokioIo;
66
use hyper_util::server::graceful::GracefulShutdown;
77
use ngyn_shared::core::engine::{NgynHttpPlatform, PlatformData};
88
use ngyn_shared::server::NgynResponse;
9+
use std::io::Error;
910
use std::sync::Arc;
1011
use tokio::net::TcpListener;
1112

@@ -78,37 +79,53 @@ impl HyperApplication {
7879
// when this signal completes, start shutdown
7980
let mut signal = std::pin::pin!(shutdown_signal());
8081

82+
// Channel for error propagation from spawned tasks
83+
let (error_sender, mut error_receiver) = tokio::sync::mpsc::channel::<std::io::Error>(100);
84+
8185
loop {
8286
let data = data.clone();
8387
tokio::select! {
8488
Ok((stream, _)) = server.accept() => {
8589
let io = TokioIo::new(stream);
8690
let conn = http1.serve_connection(io, service_fn(move |req| hyper_service(data.clone(), req)));
8791
let handle = graceful.watch(conn);
92+
let error_sender = error_sender.clone();
8893

8994
tokio::task::spawn(async move {
9095
if let Err(e) = handle.await {
91-
eprintln!("server connection error: {}", e);
96+
let io_error = std::io::Error::new(
97+
std::io::ErrorKind::Other,
98+
format!("internal server error: {}", e)
99+
);
100+
let _ = error_sender.send(io_error).await;
92101
}
93102
});
94103
}
104+
Some(err) = error_receiver.recv() => {
105+
// Return the first error we receive
106+
return Err(err);
107+
}
95108
_ = &mut signal => {
96-
eprintln!("graceful shutdown signal received");
97109
// stop the accept loop
98110
break;
99111
}
100112
else => continue, // continue waiting for the next signal or connection
101113
}
102114
}
103115

116+
// Handle graceful shutdown with timeout
104117
tokio::select! {
105118
_ = graceful.shutdown() => {
106-
eprintln!("all connections gracefully closed");
119+
Ok(())
120+
},
121+
Some(err) = error_receiver.recv() => {
122+
// Propagate any connection errors that occurred during shutdown
123+
Err(err)
107124
},
108125
_ = tokio::time::sleep(std::time::Duration::from_secs(10)) => {
109-
eprintln!("timed out wait for all connections to close");
126+
Err(Error::new(std::io::ErrorKind::TimedOut, "graceful shutdown timed out"))
110127
}
111-
}
128+
}?;
112129

113130
Ok(())
114131
}

0 commit comments

Comments
 (0)