Files
Roey Berman b41a032dd4 Enable HTTP/2 keepalive on nexus and callback transports (#11581)
Outbound nexus operation and callback requests used transports without
HTTP/2 health checks: the CHASM nexus transport provider returned the
global http.DefaultTransport, and both callback HTTPCallerProviders used
a zero-value http.Client. A silently broken connection (peer dropped it
without a GOAWAY or RST) therefore stays in the pool and stalls every
request multiplexed onto it until their individual deadlines expire.

Add common.NewHTTPTransport, which builds a transport with
http.DefaultTransport's field values and sets ReadIdleTimeout=15s /
PingTimeout=5s via http2.ConfigureTransports, and use it for:

- chasm/lib/nexusoperation (also covers components/nexusoperations,
which bridges to the same ClientProvider)
- chasm/lib/callback and components/callbacks
- RPCFactory.createLocalFrontendHTTPClient, used for worker-target nexus
calls and local callbacks
- FrontendHTTPClientCache.newClientForCluster, used for cross-cluster
callbacks

The last two already hand-rolled the same copy of DefaultTransport's
fields, so they now share it.

The helper takes the TLS config as a parameter instead of letting
callers assign it afterwards: h2 is negotiated via ALPN, so replacing
TLSClientConfig after http2.ConfigureTransports would silently fall back
to HTTP/1.1. It clones the config, since both frontend clients pass one
cached by localStoreTlsProvider and shared with gRPC clients, and
enabling h2 appends to NextProtos. Cert rotation is unaffected as it
goes through the GetClientCertificate callback, which Clone carries
over.

Note that cleartext h2c is not negotiated, so for the two frontend
clients the keepalive only applies when TLS is configured.

Also drop components/nexusoperations.ResponseSizeLimiter along with the
LimitedReadCloser it was the only user of. It had no callers: the CHASM
clientProviderFactory is what wraps the transport now, via its own
responseSizeLimiter built on http.MaxBytesReader. Being exported, the
dead code escaped the unused linter. ErrResponseBodyTooLarge moves to
executors.go, which still raises it from the payload size check.
2026-08-17 08:49:29 -07:00
..
2026-06-22 12:24:10 -07:00