-
Notifications
You must be signed in to change notification settings - Fork 18.6k
Description
Consider the following code:
package main
import (
"fmt"
"time"
"net/http"
"io/ioutil"
)
func main(){
b,err:=GetDataFromMyServer(time.Second*5)
fmt.Println(string(b),err)
return
}
func GetDataFromMyServer(timeout time.Duration) (b []byte,err error){
httpClient:=&http.Client{
Transport: &http.Transport{
Dial: net.Dial, // or something with a proxy implement.
},
Timeout: timeout,
}
defer CloseGoHttpClient(httpClient)
resp,err:=httpClient.Get("https://www.google.com/")
if err!=nil{
return nil,err
}
defer resp.Body.Close()
return ioutil.ReadAll(resp.Body)
}
func CloseGoHttpDefaultIdleConnections() {
if http.DefaultTransport==nil{
return
}
tran,ok:=http.DefaultTransport.(*http.Transport)
if !ok{
return
}
tran.CloseIdleConnections()
}
func CloseGoHttpClient(client *http.Client){
CloseGoHttpDefaultIdleConnections()
if client.Transport==nil{
return
}
tran,ok:=client.Transport.(*http.Transport)
if !ok{
return
}
tran.CloseIdleConnections()
}I know that the *http.Client need to be closed or it will leak memory or connections in the process and make a out of memory error after create a lot of it.
It is too complex for a normal programmer to understand how to close a *http.Client (or even know that the *http.Client object need close).
So I think add a func Close() error method to it, should make the programmer think it looks like a *os.File, it need to be closed after using it.
In our team, several new golang programmers made a out of memory and too many connections from creating too many *http.Client object, and forget to close it.
Here is a bug caused by *http.Client object manage:
softlayer/softlayer-go#88
There is not document of how to close a *http.Client, it just say Clients should be reused instead of created as needed., it do not say the create a lot of *http.Client and do not close it will cause leak memory:
https://golang.org/pkg/net/http/#Client