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.
master
Anis Elleuch 6 years ago committed by Harshavardhana
parent bfb505aa8e
commit 69bd6df464
  1. 21
      cmd/rest/client.go
  2. 1
      cmd/storage-rest-client.go

@ -36,6 +36,7 @@ const DefaultRESTTimeout = 1 * time.Minute
// Client - http based RPC client. // Client - http based RPC client.
type Client struct { type Client struct {
httpClient *http.Client httpClient *http.Client
httpIdleConnsCloser func()
url *url.URL url *url.URL
newAuthToken func() string newAuthToken func() string
} }
@ -67,6 +68,13 @@ func (c *Client) Call(method string, values url.Values, body io.Reader) (reply i
return resp.Body, nil 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) { 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) { return func(ctx context.Context, network, addr string) (net.Conn, error) {
dialer := &net.Dialer{ dialer := &net.Dialer{
@ -84,13 +92,11 @@ 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 { func NewClient(url *url.URL, tlsConfig *tls.Config, timeout time.Duration, newAuthToken func() string) *Client {
return &Client{
httpClient: &http.Client{
// Transport is exactly same as Go default in https://golang.org/pkg/net/http/#RoundTripper // Transport is exactly same as Go default in https://golang.org/pkg/net/http/#RoundTripper
// except custom DialContext and TLSClientConfig. // except custom DialContext and TLSClientConfig.
Transport: &http.Transport{ tr := &http.Transport{
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
DialContext: newCustomDialContext(timeout), DialContext: newCustomDialContext(timeout),
MaxIdleConnsPerHost: 4096, MaxIdleConnsPerHost: 4096,
@ -100,8 +106,11 @@ func NewClient(url *url.URL, tlsConfig *tls.Config, timeout time.Duration, newAu
ExpectContinueTimeout: 1 * time.Second, ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: tlsConfig, TLSClientConfig: tlsConfig,
DisableCompression: true, DisableCompression: true,
}, }
},
return &Client{
httpClient: &http.Client{Transport: tr},
httpIdleConnsCloser: tr.CloseIdleConnections,
url: url, url: url,
newAuthToken: newAuthToken, newAuthToken: newAuthToken,
} }

@ -322,6 +322,7 @@ func (client *storageRESTClient) RenameFile(srcVolume, srcPath, dstVolume, dstPa
// Close - marks the client as closed. // Close - marks the client as closed.
func (client *storageRESTClient) Close() error { func (client *storageRESTClient) Close() error {
client.connected = false client.connected = false
client.restClient.Close()
return nil return nil
} }

Loading…
Cancel
Save