Repository navigation
Conversation
Motivation: Long-lived HTTP/2 connections (as used by gRPC) lead to an uneven load distribution across server instances: clients stay connected to the instances they found at connect time, and instances added later (after a scale-out or a rolling deploy) receive no share of the existing traffic. The server is the side that can retire a connection gracefully, via GOAWAY. grpc-java offers this as maxConnectionAge; pekko-http has no equivalent (akka/akka-grpc#967 is the corresponding request on the Akka side). Modification: Backport to 1.4.x of the main-branch change adding a `pekko.http.server.http2.max-connection-age` setting, default `infinite` (disabled). When a server connection reaches the configured age, the existing graceful termination path is triggered: GOAWAY(NO_ERROR) is sent, streams that are in flight complete normally, streams opened after the GOAWAY are refused with RST_STREAM(REFUSED_STREAM), and the connection is closed once no streams remain. The age is jittered per connection by a configurable fraction, `max-connection-age-jitter` (default 0.1 = +/- 10%, the value grpc-java applies; 0 disables jitter), so that connections that were opened together are not all closed at the same time. `triggerTermination` now accepts an infinite deadline, in which case no forced-close timer is scheduled. Also corrects the termination debug log, which printed the timer key instead of the deadline. Branch adaptations relative to main: `@since` tags say 1.4.1, the MiMa filter file lives in 1.4.x.backwards.excludes, and getMaxConnectionAge converts the possibly-infinite duration inline because JavaDurationConverter does not exist on this branch. Result: Operators can cap the lifetime of server-side HTTP/2 connections to rebalance long-lived connections across server instances. Behavior is unchanged by default. Tests: - sbt "http2-tests/test": 344 tests pass, including 2 new directional tests for max-connection-age in Http2ServerSpec - PR_TARGET_BRANCH=origin/1.4.x sbt validatePullRequest: all tasks pass except docs/Compile/paradox, which fails identically on a clean checkout of 1.4.x in this environment (pegdown/parboiled parser bootstrap error) - environment issue, not caused by this change - sbt "+http-core/mimaReportBinaryIssues": clean, with 5 new ReversedMissingMethodProblem filters for the added methods - sbt scalafmtCheckAll scalafmtSbtCheck: clean - sbt headerCreateAll: no changes - manual end-to-end check against grpc-java 1.75.0, built from this branch: with max-connection-age = 5s, a client calling every 200 ms for 16 s saw 0 failures across the connection retirements, and a unary call that was in flight when the GOAWAY was sent completed normally References: Refs akka/akka-grpc#967 - equivalent request against akka-http/akka-grpc. 1.4.x companion of the main-branch pull request adding the same setting.
Member
|
Let's wait till the first PR is reviewed. Please close this. |
Kreinoee
marked this pull request as ready for review
September 24, 2026 18:04
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Backport of #1316 to the 1.4.x line, so that the setting is usable before 2.0.0 ships.
See that PR for the full motivation: a
max-connection-agefor HTTP/2 server connections, theserver-side counterpart of grpc-java's
maxConnectionAge(akka/akka-grpc#967 is the correspondingrequest on the Akka side).
Modification
Cherry-pick of the single commit on #1316, with the branch-specific adaptations:
@sincetags say1.4.1(this line) instead of2.0.0(main), following the precedent ofmax-header-list-size (http/2: bound incoming header blocks with max-header-list-size #1247).
1.4.x.backwards.excludes.getMaxConnectionAgeconverts the possibly-infinite Scala duration inline(
ChronoUnit.FOREVER.getDurationfor infinite), becauseJavaDurationConverterdoes not exist onthis branch.
Result
Same as #1316: operators can cap the lifetime of server-side HTTP/2 connections to
rebalance long-lived connections across server instances. Behavior is unchanged by default.
Verified against a real grpc-java (1.75.0) client, same setup as on #1316 but built from
this branch: with
max-connection-age = 5s, a client issuing a unary call every 200 ms for 16 sobserved 0 failures across the connection retirements (the server saw 3 distinct client
connections), and a unary call that was in flight when the GOAWAY was sent completed normally on the
connection being drained.
Tests
sbt "http2-tests/test": pass, including the 2 new directional tests for max-connection-age inHttp2ServerSpecPR_TARGET_BRANCH=origin/1.4.x sbt validatePullRequest: all tasks pass exceptdocs/Compile/paradox,which fails in this environment on a clean checkout of
1.4.xtoo (see the docs/paradox note below)sbt "+http-core/mimaReportBinaryIssues": cleansbt scalafmtCheckAll scalafmtSbtCheck: cleansbt docs/paradox: environment failure unrelated to this change (fails identically on a cleancheckout of
1.4.xwithError creating extended parser class ... org.pegdown.ParserWithDirectives)References
Backport of #1316. Refs akka/akka-grpc#967.