Skip to content

feat(server): add max_connection_age + grace knob to BoundServer #151

@gsalingu

Description

@gsalingu

Summary

The BoundServer API has no way to configure a per-connection maximum age. This means servers cannot proactively evict long-lived HTTP/2 connections via GOAWAY, which is recommended for load-balanced deployments (prevents connection pinning, enables zero-downtime rolling restarts).

Tonic provides this via its MaxConnectionAge tower layer. We would like parity in connectrpc.rs.

Proposed API

```rust
impl BoundServer {
/// Send GOAWAY after a connection has been alive for `duration`.
///
/// A jitter of up to 10% is applied automatically to prevent thundering-herd
/// reconnects in large fleets.
pub fn max_connection_age(mut self, duration: Duration) -> Self { ... }

/// Grace period after the first GOAWAY before forcibly closing the connection.
///
/// During the grace window the server sends a second GOAWAY, waits for
/// in-flight streams to complete, then drops the connection. Defaults to
/// some reasonable value (e.g. 5 s) if not set.
pub fn max_connection_age_grace(mut self, duration: Duration) -> Self { ... }

}
```

Why this matters

In Kubernetes and other orchestrated environments, services rely on max-connection-age to ensure clients reconnect periodically, distributing load across pod restarts. Without it, the operator must implement this at the service-kit / middleware layer, duplicating logic that properly belongs in the transport.

Prior art

  • tonic: tonic::transport::Server::max_connection_age (wraps a tower layer)
  • grpc-go: keepalive.ServerParameters.MaxConnectionAge
  • envoy: max_connection_duration in HTTP/2 options

References

  • RFC 9113 §9.3 (HTTP/2 GOAWAY semantics)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions