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. 51
      cmd/rest/client.go
  2. 1
      cmd/storage-rest-client.go

@ -35,9 +35,10 @@ 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
url *url.URL httpIdleConnsCloser func()
newAuthToken func() string url *url.URL
newAuthToken func() string
} }
// Call - make a REST call. // 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 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,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 { 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{ return &Client{
httpClient: &http.Client{ httpClient: &http.Client{Transport: tr},
// Transport is exactly same as Go default in https://golang.org/pkg/net/http/#RoundTripper httpIdleConnsCloser: tr.CloseIdleConnections,
// except custom DialContext and TLSClientConfig. url: url,
Transport: &http.Transport{ newAuthToken: newAuthToken,
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,
} }
} }

@ -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