The GitHub Actions job "Validate and test" on pekko-http.git/main has succeeded. Run started by GitHub user pjfanning (triggered by pjfanning).
Head commit for run: 478c58bb733fadbe921660bccc964311ad58e9ef / Anders Kreinøe <[email protected]> feat: add max-connection-age setting for HTTP/2 server connections (#1316) * feat: add max-connection-age setting for HTTP/2 server connections 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: Add 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. 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": 376 tests pass, including 2 new directional tests for max-connection-age in Http2ServerSpec - sbt validatePullRequest: passes - sbt "+http-core/mimaReportBinaryIssues": clean, with 5 new ReversedMissingMethodProblem filters for the added methods - sbt checkCodeStyle: clean; sbt headerCreateAll: no changes - sbt docs/paradox: builds, remaining warnings pre-existing - sbt sortImports: environment failure unrelated to this change (http/scalafixAll fails with NoSuchMethodError in scala.meta on a clean checkout of main too); the files changed here are sort-clean - manual end-to-end check against grpc-java 1.75.0: with max-connection-age = 5s, a client calling every 200 ms for 16 s saw 0 failures across 3 connection retirements, and a unary call that was in flight when the GOAWAY was sent completed normally References: None - no pekko-http issue tracks this; akka/akka-grpc#967 is the equivalent request against akka-http/akka-grpc. * Set @since of the new settings to 1.4.2 as requested in review * Revert "Set @since of the new settings to 1.4.2 as requested in review" This reverts commit 9ce450d826db93c02a9089d8a882d449456b25ee. * Map ChronoUnit.FOREVER back to Duration.Inf in the Java withMaxConnectionAge withMaxConnectionAge(getMaxConnectionAge) threw ArithmeticException on the default settings: toMillis overflows on ChronoUnit.FOREVER.getDuration, the value getMaxConnectionAge returns for an infinite age. Adds the inverse of JavaDurationConverter.toJava and a round-trip test. * Document when JavaDurationConverter.toScala throws * Make the infinite round-trip test independent of the default max-connection-age * Add max-connection-age-grace to bound the drain after max-connection-age The drain started by the MaxConnectionAge timer had no deadline, so a stream that never completes kept the connection open indefinitely. The new setting bounds it, with a default of 30s. The value infinite keeps the previous behaviour of waiting for all requests in flight to complete. * Drop the grpc-java aside from the max-connection-age-grace comment * Let a later terminate shorten a termination that is already in progress triggerTermination ignored every call after the first, so a server binding termination could not enforce its deadline on a connection that was already draining after max-connection-age. Now an earlier deadline reschedules the forced close, a later one is ignored. The max-connection-age timer is cancelled once any termination starts, so the age and its grace period never shorten a termination in progress. * Guard the max-connection-age timer instead of cancelling it when a termination starts Same behaviour, but the rule is visible where it applies: the timer handler checks whether a termination is already in progress and logs that there is nothing to do, rather than relying on the cancelled timer's message being dropped by the stage. * Name scheduleForcedCloseIfEarlier after what it does instead of commenting it * Say what an age expiry does on a connection that is already terminating, next to the age setting * State that max-connection-age applies to HTTP/2 only, and reword the jitter test comment * Do not point server-side forced-close logging at the client-only completion-timeout setting The message is shared by both sides. On the client the deadline is the completion-timeout setting, on the server it is the deadline passed to terminate or the max-connection-age-grace setting. * Do not blame the peer in the server-side forced-close log message Report URL: https://github.com/apache/pekko-http/actions/runs/36989204277 With regards, GitHub Actions via GitBox --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
