Turning off connection pool for Go http.Client
You need to set the DisableKeepAlives
to true
, and MaxIdleConnsPerHost
to -1.
From the documentation:
// DisableKeepAlives, if true, disables HTTP keep-alives and
// will only use the connection to the server for a single
// HTTP request.
https://golang.org/src/net/http/transport.go, line 166 and 187
So, your client have to be initialized as following
c = &http.Client{
Transport: &http.Transport{
DialContext: (&net.Dialer{
Timeout: 5 * time.Second,
}).DialContext,
TLSHandshakeTimeout: 5 * time.Second,
ResponseHeaderTimeout: 5 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
DisableKeepAlives: true,
MaxIdleConnsPerHost: -1
},
}
If you are using a Go version prior than 1.7, than you need to consume all the buffer of the body and only after call the request.Body.Close()
. Instead, if you are using a version greater or equal the 1.7, you can defer the close without additional precautions.
Example library that has connection pooling disabled, but is still able to perform parallel requests: https://github.com/alessiosavi/Requests
Connections are added to the pool in the function Transport.tryPutIdleConn. The connection is not pooled if Transport.DisableKeepAlives is true or Transport.MaxIdleConnsPerHost is less than zero.
Setting either value disables pooling. The transport adds the Connection: close
request header when DisableKeepAlives is true. This may or may not be desirable depending on what you are testing.
Here's how to set DisableKeepAlives:
t := http.DefaultTransport.(*http.Transport).Clone()
t.DisableKeepAlives = true
c := &http.Client{Transport: t}
Run a demonstration of DisableKeepAlives = true on the playground.
Here's how to set MaxIdleConnsPerHost:
t := http.DefaultTransport.(*http.Transport).Clone()
t.MaxIdleConnsPerHost = -1
c := &http.Client{Transport: t}
Run a demonstration of MaxIdleConnsPerHost = -1 on the playground.
The code above clones the default transport to ensure that the default transport options are used. If you explicitly want the options in the question, then use
c = &http.Client{
Transport: &http.Transport{
DialContext: (&net.Dialer{
Timeout: 5 * time.Second,
KeepAlive: 5 * time.Second,
}).DialContext,
TLSHandshakeTimeout: 5 * time.Second,
ResponseHeaderTimeout: 5 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
DisableKeepAlives: true,
},
}
or
c = &http.Client{
Transport: &http.Transport{
DialContext: (&net.Dialer{
Timeout: 5 * time.Second,
KeepAlive: 5 * time.Second,
}).DialContext,
TLSHandshakeTimeout: 5 * time.Second,
ResponseHeaderTimeout: 5 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
MaxIdleConnsPerHost: -1,
},
}
MaxIdleConnsPerHost does not limit the number of active connections per host. See this playground example for a demonstration.
Pooling is not disabled by setting Dialer.KeepAlive to -1. See this answer for an explanation.