From c2ff762ec2c036284f19bba2b67b66d49c63a663 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Thu, 15 Apr 2021 23:30:21 -0400 Subject: [PATCH] feat(transport): configure HTTP/2 ReadIdleTimeout (#882) Setting this config causes the HTTP/2 transport to send a ping on idle connections every 15s and prune ones that have been severed. This should give increased reliability during network issues between the client and CFE. --- go.mod | 1 + transport/http/configure_http2_go116.go | 25 +++++++++++++++++++++ transport/http/configure_http2_not_go116.go | 16 +++++++++++++ transport/http/dial.go | 4 ++++ 4 files changed, 46 insertions(+) create mode 100644 transport/http/configure_http2_go116.go create mode 100644 transport/http/configure_http2_not_go116.go diff --git a/go.mod b/go.mod index 65031d972fa..91b3782d02f 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/googleapis/gax-go/v2 v2.0.5 go.opencensus.io v0.23.0 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 + golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750 diff --git a/transport/http/configure_http2_go116.go b/transport/http/configure_http2_go116.go new file mode 100644 index 00000000000..2f0335fb1fc --- /dev/null +++ b/transport/http/configure_http2_go116.go @@ -0,0 +1,25 @@ +// Copyright 2021 Google LLC. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.16 + +package http + +import ( + "net/http" + "time" + + "golang.org/x/net/http2" +) + +// configureHTTP2 configures the ReadIdleTimeout HTTP/2 option for the +// transport. This allows broken idle connections to be pruned more quickly, +// preventing the client from attempting to re-use connections that will no +// longer work. +func configureHTTP2(trans *http.Transport) { + http2Trans, err := http2.ConfigureTransports(trans) + if err == nil { + http2Trans.ReadIdleTimeout = time.Second * 15 + } +} diff --git a/transport/http/configure_http2_not_go116.go b/transport/http/configure_http2_not_go116.go new file mode 100644 index 00000000000..78b2b5f6ba1 --- /dev/null +++ b/transport/http/configure_http2_not_go116.go @@ -0,0 +1,16 @@ +// Copyright 2021 Google LLC. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.16 + +package http + +import ( + "net/http" +) + +// configureHTTP2 configures the ReadIdleTimeout HTTP/2 option for the +// transport. The interface to do this is only available in Go 1.16 and up, so +// this performs a no-op. +func configureHTTP2(trans *http.Transport) {} diff --git a/transport/http/dial.go b/transport/http/dial.go index fcd0209fbcf..179534a0c7c 100644 --- a/transport/http/dial.go +++ b/transport/http/dial.go @@ -175,6 +175,10 @@ func defaultBaseTransport(ctx context.Context, clientCertSource cert.Source) htt } } + // If possible, configure http2 transport in order to use ReadIdleTimeout + // setting. This can only be done in Go 1.16 and up. + configureHTTP2(trans) + return trans }