From c710ddf113dbd7d030f7b477cc02d7c911483cd9 Mon Sep 17 00:00:00 2001 From: Peter Broadhurst Date: Thu, 3 Feb 2022 08:59:41 -0500 Subject: [PATCH] Set default keepalive timeout to 5s on clients for Node.js connectors Signed-off-by: Peter Broadhurst --- internal/restclient/config.go | 32 ++++++++++++++++++++++++++------ internal/restclient/ffresty.go | 20 ++++++++++++++++++-- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/internal/restclient/config.go b/internal/restclient/config.go index 9585197fad..91bbf32c8d 100644 --- a/internal/restclient/config.go +++ b/internal/restclient/config.go @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2022 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -19,11 +19,16 @@ package restclient import "github.com/hyperledger/firefly/internal/config" const ( - defaultRetryEnabled = false - defaultRetryCount = 5 - defaultRetryWaitTime = "250ms" - defaultRetryMaxWaitTime = "30s" - defaultRequestTimeout = "30s" + defaultRetryEnabled = false + defaultRetryCount = 5 + defaultRetryWaitTime = "250ms" + defaultRetryMaxWaitTime = "30s" + defaultRequestTimeout = "30s" + defaultHTTPIdleTimeout = "475ms" // Node.js default keepAliveTimeout is 5 seconds, so we have to set a base below this + defaultHTTPMaxIdleConns = 100 // match Go's default + defaultHTTPConnectionTimeout = "30s" + defaultHTTPTLSHandshakeTimeout = "10s" // match Go's default + defaultHTTPExpectContinueTimeout = "1s" // match Go's default ) const ( @@ -47,6 +52,16 @@ const ( HTTPConfigRetryMaxDelay = "retry.maxWaitTime" // HTTPConfigRequestTimeout the request timeout HTTPConfigRequestTimeout = "requestTimeout" + // HTTPIdleTimeout the max duration to hold a HTTP keepalive connection between calls + HTTPIdleTimeout = "idleTimeout" + // HTTPMaxIdleConns the max number of idle connections to hold pooled + HTTPMaxIdleConns = "maxIdleConns" + // HTTPConnectionTimeout the connection timeout for new connections + HTTPConnectionTimeout = "connectionTimeout" + // HTTPTLSHandshakeTimeout the TLS handshake connection timeout + HTTTPTLSHandshakeTimeout = "tlsHandshakeTimeout" + // HTTPExpectContinueTimeout see ExpectContinueTimeout in Go docs + HTTPExpectContinueTimeout = "expectContinueTimeout" // HTTPCustomClient - unit test only - allows injection of a custom HTTP client to resty HTTPCustomClient = "customClient" @@ -63,6 +78,11 @@ func InitPrefix(prefix config.KeySet) { prefix.AddKnownKey(HTTPConfigRetryInitDelay, defaultRetryWaitTime) prefix.AddKnownKey(HTTPConfigRetryMaxDelay, defaultRetryMaxWaitTime) prefix.AddKnownKey(HTTPConfigRequestTimeout, defaultRequestTimeout) + prefix.AddKnownKey(HTTPIdleTimeout, defaultHTTPIdleTimeout) + prefix.AddKnownKey(HTTPMaxIdleConns, defaultHTTPMaxIdleConns) + prefix.AddKnownKey(HTTPConnectionTimeout, defaultHTTPConnectionTimeout) + prefix.AddKnownKey(HTTTPTLSHandshakeTimeout, defaultHTTPTLSHandshakeTimeout) + prefix.AddKnownKey(HTTPExpectContinueTimeout, defaultHTTPExpectContinueTimeout) prefix.AddKnownKey(HTTPCustomClient) } diff --git a/internal/restclient/ffresty.go b/internal/restclient/ffresty.go index 0536a9982e..36f93c80b2 100644 --- a/internal/restclient/ffresty.go +++ b/internal/restclient/ffresty.go @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2022 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -21,6 +21,7 @@ import ( "encoding/base64" "fmt" "io/ioutil" + "net" "net/http" "strings" "time" @@ -70,7 +71,22 @@ func New(ctx context.Context, staticConfig config.Prefix) *resty.Client { } } if client == nil { - client = resty.New() + httpTransport := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: staticConfig.GetDuration(HTTPConnectionTimeout), + KeepAlive: staticConfig.GetDuration(HTTPConnectionTimeout), + }).DialContext, + ForceAttemptHTTP2: true, + MaxIdleConns: staticConfig.GetInt(HTTPMaxIdleConns), + IdleConnTimeout: staticConfig.GetDuration(HTTPIdleTimeout), + TLSHandshakeTimeout: staticConfig.GetDuration(HTTTPTLSHandshakeTimeout), + ExpectContinueTimeout: staticConfig.GetDuration(HTTPExpectContinueTimeout), + } + httpClient := &http.Client{ + Transport: httpTransport, + } + client = resty.NewWithClient(httpClient) } url := strings.TrimSuffix(staticConfig.GetString(HTTPConfigURL), "/")