v0.25.1
This commit is contained in:
1 parent
87e571c170
commit
fa7abc9e53
308 files changed
+49746
-50237
No files matched your search
@@ -0,0 +1,102 @@
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn http2_connection<I>(
|
||||
stream: I,
|
||||
router: Router,
|
||||
peer: SocketAddr,
|
||||
local: SocketAddr,
|
||||
transport: Transport,
|
||||
extended_connect: bool,
|
||||
lease: Arc<ConnectionLease>,
|
||||
stop: CancellationToken,
|
||||
grace: Duration,
|
||||
settings: Http2Connections,
|
||||
) where
|
||||
I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||
{
|
||||
let request_stop = stop.clone();
|
||||
let connection_metrics = lease.metrics.clone();
|
||||
let activity = H2ConnectionState::new();
|
||||
let service_activity = activity.clone();
|
||||
let service = service_fn(move |mut request: Request<Incoming>| {
|
||||
let stream_lease = H2StreamLease::begin(service_activity.clone());
|
||||
request.extensions_mut().insert(PeerAddr(peer));
|
||||
request.extensions_mut().insert(LocalAddr(local));
|
||||
request.extensions_mut().insert(transport);
|
||||
request.extensions_mut().insert(lease.clone());
|
||||
request
|
||||
.extensions_mut()
|
||||
.insert(ServerShutdown(request_stop.clone()));
|
||||
let router = router.clone();
|
||||
async move {
|
||||
router
|
||||
.oneshot(request.map(Body::new))
|
||||
.await
|
||||
.map(|response| {
|
||||
response.map(|body| Body::new(H2TrackedBody::new(body, stream_lease)))
|
||||
})
|
||||
}
|
||||
});
|
||||
let _active_http2 = ActiveHttp2Connection::begin(connection_metrics);
|
||||
let stream = H2ActivityIo::new(stream, activity.clone());
|
||||
let mut builder = http2::Builder::new(TokioExecutor::new());
|
||||
builder
|
||||
.timer(TokioTimer::new())
|
||||
.max_concurrent_streams(64)
|
||||
.max_header_list_size(32_768)
|
||||
.max_send_buf_size(65_536)
|
||||
.initial_stream_window_size(65_535)
|
||||
.initial_connection_window_size(1_048_576);
|
||||
if extended_connect {
|
||||
builder.enable_connect_protocol();
|
||||
}
|
||||
let conn = builder.serve_connection(TokioIo::new(stream), service);
|
||||
tokio::pin!(conn);
|
||||
|
||||
let max_lifetime = settings.max_connection_lifetime();
|
||||
let lifetime = async move {
|
||||
if let Some(duration) = max_lifetime {
|
||||
tokio::time::sleep(duration).await;
|
||||
} else {
|
||||
std::future::pending::<()>().await;
|
||||
}
|
||||
};
|
||||
tokio::pin!(lifetime);
|
||||
|
||||
let cause = loop {
|
||||
tokio::select! {
|
||||
result = &mut conn => {
|
||||
if let Err(error) = result {
|
||||
tracing::debug!(%error, "HTTP/2 connection closed");
|
||||
}
|
||||
return;
|
||||
},
|
||||
_ = stop.cancelled() => break H2ShutdownCause::Process,
|
||||
_ = &mut lifetime => break H2ShutdownCause::Lifetime,
|
||||
_ = wait_for_h2_idle(activity.clone(), settings.idle_timeout()) => {
|
||||
// Re-check immediately before GOAWAY so activity racing the timer
|
||||
// cannot turn a busy connection into an idle shutdown.
|
||||
if activity.is_idle(settings.idle_timeout()) {
|
||||
break H2ShutdownCause::Idle;
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// Hyper's graceful shutdown sends GOAWAY and refuses newer streams while
|
||||
// continuing to poll streams that were already accepted.
|
||||
conn.as_mut().graceful_shutdown();
|
||||
let configured_drain = settings.drain_timeout();
|
||||
let drain = if matches!(cause, H2ShutdownCause::Process) {
|
||||
std::cmp::min(configured_drain, grace)
|
||||
} else {
|
||||
configured_drain
|
||||
};
|
||||
match tokio::time::timeout(drain, &mut conn).await {
|
||||
Ok(Ok(())) => tracing::debug!(?cause, "HTTP/2 graceful shutdown drained"),
|
||||
Ok(Err(error)) => tracing::debug!(?cause, %error, "HTTP/2 graceful shutdown ended with protocol error"),
|
||||
Err(_) => tracing::debug!(?cause, drain_seconds = drain.as_secs_f64(), "HTTP/2 drain timeout reached; closing transport"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
include!("serve/tests.rs");
|
||||
Reference in new issue
Block a user