From 69bd6df4645102aa265226294be0cb81407a7505 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Tue, 20 Nov 2018 20:07:19 +0100 Subject: [PATCH] storage: Implement Close() in REST client (#6826) Calling /minio/prometheuses/metrics calls xlSets.StorageInfo() which creates a new storage REST client and closes it. However, currently, closing does nothing to the underlying opened http client. This commit introduces a closing behavior by calling CloseIdleConnections provided by http.Transport upon the initialization of this latter. --- cmd/rest/client.go | 51 ++++++++++++++++++++++---------------- cmd/storage-rest-client.go | 1 + 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/cmd/rest/client.go b/cmd/rest/client.go index 35933aa95..e201233b3 100644 --- a/cmd/rest/client.go +++ b/cmd/rest/client.go @@ -35,9 +35,10 @@ const DefaultRESTTimeout = 1 * time.Minute // Client - http based RPC client. type Client struct { - httpClient *http.Client - url *url.URL - newAuthToken func() string + httpClient *http.Client + httpIdleConnsCloser func() + url *url.URL + newAuthToken func() string } // Call - make a REST call. @@ -67,6 +68,13 @@ func (c *Client) Call(method string, values url.Values, body io.Reader) (reply i return resp.Body, nil } +// Close closes all idle connections of the underlying http client +func (c *Client) Close() { + if c.httpIdleConnsCloser != nil { + c.httpIdleConnsCloser() + } +} + func newCustomDialContext(timeout time.Duration) func(ctx context.Context, network, addr string) (net.Conn, error) { return func(ctx context.Context, network, addr string) (net.Conn, error) { dialer := &net.Dialer{ @@ -84,25 +92,26 @@ func newCustomDialContext(timeout time.Duration) func(ctx context.Context, netwo } } -// NewClient - returns new RPC client. +// NewClient - returns new REST client. func NewClient(url *url.URL, tlsConfig *tls.Config, timeout time.Duration, newAuthToken func() string) *Client { + // Transport is exactly same as Go default in https://golang.org/pkg/net/http/#RoundTripper + // except custom DialContext and TLSClientConfig. + tr := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: newCustomDialContext(timeout), + MaxIdleConnsPerHost: 4096, + MaxIdleConns: 4096, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + TLSClientConfig: tlsConfig, + DisableCompression: true, + } + return &Client{ - httpClient: &http.Client{ - // Transport is exactly same as Go default in https://golang.org/pkg/net/http/#RoundTripper - // except custom DialContext and TLSClientConfig. - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: newCustomDialContext(timeout), - MaxIdleConnsPerHost: 4096, - MaxIdleConns: 4096, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - TLSClientConfig: tlsConfig, - DisableCompression: true, - }, - }, - url: url, - newAuthToken: newAuthToken, + httpClient: &http.Client{Transport: tr}, + httpIdleConnsCloser: tr.CloseIdleConnections, + url: url, + newAuthToken: newAuthToken, } } diff --git a/cmd/storage-rest-client.go b/cmd/storage-rest-client.go index f14b29341..15119bba5 100644 --- a/cmd/storage-rest-client.go +++ b/cmd/storage-rest-client.go @@ -322,6 +322,7 @@ func (client *storageRESTClient) RenameFile(srcVolume, srcPath, dstVolume, dstPa // Close - marks the client as closed. func (client *storageRESTClient) Close() error { client.connected = false + client.restClient.Close() return nil }