var client = &http.Client{
/* etc */
Timeout: (60 * time.Second),
}
func Execute(req *http.Request) (interface{}, error) {
resp, err := client.Do(req)
if resp != nil && resp.Body != nil {
defer resp.Body.Close()
}
if err != nil {
return nil, err
}
body, err := ioutil.ReadAll(resp.Body)
// deal with body
}At No. 7, the client side issues FIN, ACK but this is before the server has responded with a 200 OK in step 8. Nevertheless, in the code, client.Do will return an error of the sort "use of closed connection" and the response will be nil, meaning there is no chance to read the body...even though the server has sent the body -- it was too late, and happened after the timeout and thus after the FIN/ACK was issued by the client side.
So, here's my dilemma...on a single request / reply where we bootstrap a whole new connection like this each time, potentially losing that response (from step 8), is understandable. The timeout occurred, and anything after that is toast.
But, if you're re-using the client for many such request / replies -- thus, there are many such posts interleaved on the same connection..if a timeout occurs, I believe there is the potential to lose the response from any outstanding request on that connection, and this is really bad.
Example timeline:
1. Client.Do(request1)
2. Client.Do(request2)
So, here's my dilemma...on a single request / reply where we bootstrap a whole new connection like this each time, potentially losing that response (from step 8), is understandable. The timeout occurred, and anything after that is toast.
But, if you're re-using the client for many such request / replies -- thus, there are many such posts interleaved on the same connection..if a timeout occurs, I believe there is the potential to lose the response from any outstanding request on that connection, and this is really bad.
This is a problem, and I'm wondering outside of spinning up a whole new connection for every request/response and disabling connection re-use altogether, how can I work around this issue. Would Transport.MaxIdleConnsPerHost help here https://golang.org/pkg/net/http/#Transport ? Would that allow multiple connections to the same host, so perhaps minimizing this effect?
HTTP is certainly a request/response, but it is my understanding the the underlying TCP connection will be re-used. If a Timeout occurs on the Transport, it appears to me that the client will issue TCP RST and completely abort that TCP connection. If that happens while the client has two in-flight requests on that TCP connection, then there is the risk that the HTTP responses will both be lost, is there not?