When adding or modifying network transports/proxies/stream multiplexing (HTTP RoundTripper, SPDY↔websocket translators, port-forward websockets), treat it as a lifecycle + overload problem:
req.Body).grpc.WaitForReady(true) for notification delivery instead of assuming an existing connection will still be usable).Code sketch (resource + readiness + bounded buffers):
// 1) Resource hygiene in RoundTrip short-circuit.
func (t *FaultInjectingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
defer func() {
if req.Body != nil {
_ = req.Body.Close()
}
}()
// ... inspect req, possibly return synthesizeResponse(...) early ...
}
// 2) Connection readiness for long/fragile RPC paths.
// (pattern: wait for readiness rather than assuming the old connection is still good)
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
client := /* new grpc client over the same dial target */
if err := client.NotifyRegistrationStatus(ctx, payload /*...*/,
grpc.WaitForReady(true),
); err != nil {
return err
}
// 3) Gate websocket multiplexing concurrency/buffer growth.
// Enforce per-connection request/stream limits and timeouts.
if activeStreams.Load() > maxAllowed {
return fmt.Errorf("too many concurrent websocket streams")
}
Applying this checklist prevents subtle correctness regressions (wrong protocol state, lost notifications), leaks (unclosed bodies/connections), and production outages when switching from SPDY-like backpressure to websocket multiplexing.