Skip to content

net/http: add Client.CloseIdleConnections method #26563

@bronze1man

Description

@bronze1man

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions