feat(server): add Server::with_graceful_shutdown method
This adds a "combinator" method to `Server`, which accepts a user's future to "select" on. All connections received by the `Server` will be tracked, and if the user's future finishes, graceful shutdown will begin. - The listener will be closed immediately. - The currently active connections will all be notified to start a graceful shutdown. For HTTP/1, that means finishing the existing response and using `connection: clone`. For HTTP/2, the graceful `GOAWAY` process is started. - Once all active connections have terminated, the graceful future will return. Closes #1575
This commit is contained in:
@@ -85,7 +85,7 @@ pub struct Connecting<I, F> {
|
||||
#[must_use = "futures do nothing unless polled"]
|
||||
#[derive(Debug)]
|
||||
pub(super) struct SpawnAll<I, S> {
|
||||
serve: Serve<I, S>,
|
||||
pub(super) serve: Serve<I, S>,
|
||||
}
|
||||
|
||||
/// A future binding a connection with a Service.
|
||||
@@ -618,7 +618,7 @@ impl<I, S> SpawnAll<I, S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, S, B> Future for SpawnAll<I, S>
|
||||
impl<I, S, B> SpawnAll<I, S>
|
||||
where
|
||||
I: Stream,
|
||||
I::Error: Into<Box<::std::error::Error + Send + Sync>>,
|
||||
@@ -630,16 +630,19 @@ where
|
||||
<S::Service as Service>::Future: Send + 'static,
|
||||
B: Payload,
|
||||
{
|
||||
type Item = ();
|
||||
type Error = ::Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
pub(super) fn poll_with<F1, F2, R>(&mut self, per_connection: F1) -> Poll<(), ::Error>
|
||||
where
|
||||
F1: Fn() -> F2,
|
||||
F2: FnOnce(UpgradeableConnection<I::Item, S::Service>) -> R + Send + 'static,
|
||||
R: Future<Item=(), Error=::Error> + Send + 'static,
|
||||
{
|
||||
loop {
|
||||
if let Some(connecting) = try_ready!(self.serve.poll()) {
|
||||
let and_then = per_connection();
|
||||
let fut = connecting
|
||||
.map_err(::Error::new_user_new_service)
|
||||
// flatten basically
|
||||
.and_then(|conn| conn.with_upgrades())
|
||||
.and_then(|conn| and_then(conn.with_upgrades()))
|
||||
.map_err(|err| debug!("conn error: {}", err));
|
||||
self.serve.protocol.exec.execute(fut)?;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user