diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2023-04-26 16:05:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-26 16:05:44 +0200 |
commit | 3eda03d6d047425681cba14caca4f1fced8168dc (patch) | |
tree | 967661674bafb37410f58986cdee43d87792765e | |
parent | c4dacaddf9bd2aff43db43180b389488be7b9fc0 (diff) | |
parent | 0a7a694c87cd6268f78fd6eeb3a103c2c4e4ea47 (diff) |
Merge pull request #26869 from vespa-engine/bjorncs/http2-graceful-goaway
Use graceful GOAWAY allowing all in-flight requests to complete
-rw-r--r-- | container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java index b4c933c1168..4cdbab5f89b 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java @@ -17,7 +17,8 @@ import jakarta.servlet.AsyncEvent; import jakarta.servlet.AsyncListener; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Session; +import org.eclipse.jetty.http2.frames.GoAwayFrame; import org.eclipse.jetty.http2.server.HTTP2ServerConnection; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EofException; @@ -159,7 +160,7 @@ class HttpRequestDispatch { Connection connection = RequestUtils.getConnection(request); if (maxRequestsPerConnection > 0) { if (connection.getMessagesIn() >= maxRequestsPerConnection) { - gracefulShutdown(connection, "max-req-per-conn-exceeded"); + gracefulShutdown(connection); } } double maxConnectionLifeInSeconds = connectorConfig.maxConnectionLife(); @@ -168,19 +169,20 @@ class HttpRequestDispatch { Instant expiredAt = Instant.ofEpochMilli((long) (createdAt + maxConnectionLifeInSeconds * 1000)); boolean isExpired = Instant.now().isAfter(expiredAt); if (isExpired) { - gracefulShutdown(connection, "max-conn-life-exceeded"); + gracefulShutdown(connection); } } } - private static void gracefulShutdown(Connection connection, String reason) { - if (connection instanceof HttpConnection) { - HttpConnection http1 = (HttpConnection) connection; + private static void gracefulShutdown(Connection connection) { + if (connection instanceof HttpConnection http1) { http1.getGenerator().setPersistent(false); - } else if (connection instanceof HTTP2ServerConnection) { - HTTP2ServerConnection http2 = (HTTP2ServerConnection) connection; - // Signal Jetty to do a graceful connection shutdown with GOAWAY frame - http2.getSession().close(ErrorCode.NO_ERROR.code, reason, Callback.NOOP); + } else if (connection instanceof HTTP2ServerConnection http2) { + // Signal Jetty to do a graceful shutdown of HTTP/2 connection. + // Graceful shutdown implies a GOAWAY frame with 'Error Code' = 'NO_ERROR' and 'Last-Stream-ID' = 2^31-1. + // In-flight requests will be allowed to complete before connection is terminated. + // See https://datatracker.ietf.org/doc/html/rfc9113#name-goaway for details + ((HTTP2Session)http2.getSession()).goAway(GoAwayFrame.GRACEFUL, Callback.NOOP); } } |