Skip to content

Commit

Permalink
Add WithIdleConnTimeout HTTP client option
Browse files Browse the repository at this point in the history
  • Loading branch information
austince committed Jun 8, 2021
1 parent 9e276a1 commit aed2fd9
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
27 changes: 18 additions & 9 deletions config/http_config.go
Expand Up @@ -47,6 +47,9 @@ var DefaultHTTPClientConfig = HTTPClientConfig{
var defaultHTTPClientOptions = httpClientOptions{
keepAlivesEnabled: true,
http2Enabled: true,
// 5 minutes is typically above the maximum sane scrape interval. So we can
// use keepalive for all configurations.
idleConnTimeout: 5 * time.Minute,
}

type closeIdler interface {
Expand Down Expand Up @@ -283,6 +286,7 @@ type httpClientOptions struct {
dialContextFunc DialContextFunc
keepAlivesEnabled bool
http2Enabled bool
idleConnTimeout time.Duration
}

// HTTPClientOption defines an option that can be applied to the HTTP client.
Expand All @@ -309,6 +313,13 @@ func WithHTTP2Disabled() HTTPClientOption {
}
}

// WithIdleConnTimeout allows setting the idle connection timeout.
func WithIdleConnTimeout(timeout time.Duration) HTTPClientOption {
return func(opts *httpClientOptions) {
opts.idleConnTimeout = timeout
}
}

// NewClient returns a http.Client using the specified http.RoundTripper.
func newClient(rt http.RoundTripper) *http.Client {
return &http.Client{Transport: rt}
Expand Down Expand Up @@ -357,15 +368,13 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HT
// The only timeout we care about is the configured scrape timeout.
// It is applied on request. So we leave out any timings here.
var rt http.RoundTripper = &http.Transport{
Proxy: http.ProxyURL(cfg.ProxyURL.URL),
MaxIdleConns: 20000,
MaxIdleConnsPerHost: 1000, // see https://github.com/golang/go/issues/13801
DisableKeepAlives: !opts.keepAlivesEnabled,
TLSClientConfig: tlsConfig,
DisableCompression: true,
// 5 minutes is typically above the maximum sane scrape interval. So we can
// use keepalive for all configurations.
IdleConnTimeout: 5 * time.Minute,
Proxy: http.ProxyURL(cfg.ProxyURL.URL),
MaxIdleConns: 20000,
MaxIdleConnsPerHost: 1000, // see https://github.com/golang/go/issues/13801
DisableKeepAlives: !opts.keepAlivesEnabled,
TLSClientConfig: tlsConfig,
DisableCompression: true,
IdleConnTimeout: opts.idleConnTimeout,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
DialContext: dialContext,
Expand Down
19 changes: 19 additions & 0 deletions config/http_config_test.go
Expand Up @@ -456,6 +456,25 @@ func TestCustomDialContextFunc(t *testing.T) {
}
}

func TestCustomIdleConnTimeout(t *testing.T) {
timeout := time.Second * 5

cfg := HTTPClientConfig{}
rt, err := NewRoundTripperFromConfig(cfg, "test", WithIdleConnTimeout(timeout))
if err != nil {
t.Fatalf("Can't create a round-tripper from this config: %+v", cfg)
}

transport, ok := rt.(*http.Transport)
if !ok {
t.Fatalf("Unexpected transport: %+v", transport)
}

if transport.IdleConnTimeout != timeout {
t.Fatalf("Unexpected idle connection timeout: %+v", timeout)
}
}

func TestMissingBearerAuthFile(t *testing.T) {
cfg := HTTPClientConfig{
BearerTokenFile: MissingBearerTokenFile,
Expand Down

0 comments on commit aed2fd9

Please sign in to comment.