Comment #9 on issue 9092 by
rone...@gmail.com: net/http: Goroutine leak in
http client/transport
https://code.google.com/p/go/issues/detail?id=9092
Following is the code, it sends 3 http request and it generate three chan
receive blocks as the profile shown after the code
package main
import (
"fmt"
"net/http"
//"encoding/xml"
"bytes"
"io/ioutil"
//"log"
"net"
"net/http/httputil"
_ "net/http/pprof"
"strconv"
"time"
)
const (
CONNECTION_TIMEOUT = 20
RESPONSE_HEADER_TIMEOUT = 60
HTTP_TIMEOUT = 90
)
func TimeoutDialer(connectTimeout time.Duration) func(net, addr string)
(net.Conn, error) {
return func(network, address string) (net.Conn, error) {
conn, err := net.DialTimeout(network, address, connectTimeout)
return conn, err
}
}
func NewDefaultTimeoutClient() *http.Client {
return NewTimeoutClient(CONNECTION_TIMEOUT*time.Second,
RESPONSE_HEADER_TIMEOUT*time.Second)
}
func NewTimeoutClient(connectTimeout time.Duration, responseHeaderTimeout
time.Duration) *http.Client {
return &http.Client{
Transport: &http.Transport{
Dial: TimeoutDialer(connectTimeout),
ResponseHeaderTimeout: responseHeaderTimeout,
},
Timeout: HTTP_TIMEOUT * time.Second,
}
}
func main() {
go http.ListenAndServe(":6168", nil) //profiling
client := NewDefaultTimeoutClient()
for i := 0; i < 3; i++ {
fmt.Println("Test ", i)
content :=
fmt.Sprintf("api_key=%s&api_secret=%s&from=%s&to=%s&text=test%d&status-report-req=1",
"xxx", "xxx", "xxx", "1234", i)
buf := bytes.NewBufferString(content)
req, err := http.NewRequest("POST", "
http://xxx", buf)
if err == nil {
req.Header.Add("Content-type", "application/x-www-form-urlencoded")
req.Header.Add("Content-Length", strconv.Itoa(len(content)))
output, _ := httputil.DumpRequestOut(req, true)
fmt.Println("DEBUG: ", string(output))
resp, err := client.Do(req)
if err == nil {
respStr, err := ioutil.ReadAll(resp.Body)
if err == nil {
fmt.Println("resp: ", string(respStr))
} else {
fmt.Println("ERROR: ", err)
}
} else {
fmt.Println("ERROR: ", err)
}
resp.Body.Close()
} else {
fmt.Println("ERROR: ", err)
}
time.Sleep(30 * time.Second)
}
time.Sleep(600 * time.Second)
}
goroutine 35 [running]:
runtime/pprof.writeGoroutineStacks(0x382178, 0xc08203a140, 0x0, 0x0)
D:/Go/src/pkg/runtime/pprof/pprof.go:511 +0x93
runtime/pprof.writeGoroutine(0x382178, 0xc08203a140, 0x2, 0x0, 0x0)
D:/Go/src/pkg/runtime/pprof/pprof.go:500 +0x55
runtime/pprof.(*Profile).WriteTo(0x904e80, 0x382178, 0xc08203a140, 0x2,
0x0, 0x0)
D:/Go/src/pkg/runtime/pprof/pprof.go:229 +0xda
net/http/pprof.handler.ServeHTTP(0xc08201ae51, 0x9, 0x3820f0, 0xc08203a140,
0xc08201edd0)
D:/Go/src/pkg/net/http/pprof/pprof.go:165 +0x277
net/http/pprof.Index(0x3820f0, 0xc08203a140, 0xc08201edd0)
D:/Go/src/pkg/net/http/pprof/pprof.go:177 +0x167
net/http.HandlerFunc.ServeHTTP(0x7e6368, 0x3820f0, 0xc08203a140,
0xc08201edd0)
D:/Go/src/pkg/net/http/server.go:1235 +0x47
net/http.(*ServeMux).ServeHTTP(0xc08201a090, 0x3820f0, 0xc08203a140,
0xc08201edd0)
D:/Go/src/pkg/net/http/server.go:1511 +0x1aa
net/http.serverHandler.ServeHTTP(0xc08200e5a0, 0x3820f0, 0xc08203a140,
0xc08201edd0)
D:/Go/src/pkg/net/http/server.go:1673 +0x1a6
net/http.(*conn).serve(0xc082048600)
D:/Go/src/pkg/net/http/server.go:1174 +0xa85
created by net/http.(*Server).Serve
D:/Go/src/pkg/net/http/server.go:1721 +0x31a
goroutine 16 [sleep, 3 minutes]:
time.Sleep(0x8bb2c97000)
C:/Users/ADMINI~1/AppData/Local/Temp/2/makerelease686069423/go/src/pkg/runtime/time.goc:39
+0x38
main.main()
D:/workspace/beetalk_server/go_projects/src/
garena.com/TestSMS/TestSMS.go:75
+0x89c
goroutine 19 [finalizer wait, 7 minutes]:
runtime.park(0x4160d0, 0x910c78, 0x90e609)
D:/Go/src/pkg/runtime/proc.c:1369 +0xac
runtime.parkunlock(0x910c78, 0x90e609)
D:/Go/src/pkg/runtime/proc.c:1385 +0x42
runfinq()
D:/Go/src/pkg/runtime/mgc0.c:2644 +0xdd
runtime.goexit()
D:/Go/src/pkg/runtime/proc.c:1445
goroutine 24 [chan receive, 6 minutes]:
net/http.(*persistConn).readLoop(0xc08203e160)
D:/Go/src/pkg/net/http/transport.go:798 +0x312
created by net/http.(*Transport).dialConn
D:/Go/src/pkg/net/http/transport.go:600 +0x946
goroutine 21 [IO wait]:
net.runtime_pollWait(0x381dc0, 0x72, 0x0)
C:/Users/ADMINI~1/AppData/Local/Temp/2/makerelease686069423/go/src/pkg/runtime/netpoll.goc:146
+0x6d
net.(*pollDesc).Wait(0xc082080170, 0x72, 0x0, 0x0)
D:/Go/src/pkg/net/fd_poll_runtime.go:84 +0x4d
net.(*ioSrv).ExecIO(0xc082038078, 0xc082080060, 0x750910, 0x8,
0xc082000980, 0xc082080480, 0x0, 0x0)
D:/Go/src/pkg/net/fd_windows.go:188 +0x242
net.(*netFD).acceptOne(0xc082080000, 0x7e6298, 0xc08205a1c0, 0x2, 0x2,
0xc082080060, 0x7167a0, 0x0, 0x0)
D:/Go/src/pkg/net/fd_windows.go:539 +0x3c7
net.(*netFD).accept(0xc082080000, 0x7e6298, 0x0, 0x0, 0x0)
D:/Go/src/pkg/net/fd_windows.go:566 +0x187
net.(*TCPListener).AcceptTCP(0xc0820380d8, 0x45e0ca, 0x0, 0x0)
D:/Go/src/pkg/net/tcpsock_posix.go:234 +0x64
net/http.tcpKeepAliveListener.Accept(0xc0820380d8, 0x0, 0x0, 0x0, 0x0)
D:/Go/src/pkg/net/http/server.go:1947 +0x52
net/http.(*Server).Serve(0xc08200e5a0, 0x381f48, 0xc0820380d8, 0x0, 0x0)
D:/Go/src/pkg/net/http/server.go:1698 +0x98
net/http.(*Server).ListenAndServe(0xc08200e5a0, 0x0, 0x0)
D:/Go/src/pkg/net/http/server.go:1688 +0x154
net/http.ListenAndServe(0x7325f0, 0x5, 0x0, 0x0, 0x0, 0x0)
D:/Go/src/pkg/net/http/server.go:1778 +0x80
created by main.main
D:/workspace/beetalk_server/go_projects/src/
garena.com/TestSMS/TestSMS.go:45
+0x59
goroutine 45 [IO wait]:
net.runtime_pollWait(0x381e70, 0x72, 0x0)
C:/Users/ADMINI~1/AppData/Local/Temp/2/makerelease686069423/go/src/pkg/runtime/netpoll.goc:146
+0x6d
net.(*pollDesc).Wait(0xc0820802f0, 0x72, 0x0, 0x0)
D:/Go/src/pkg/net/fd_poll_runtime.go:84 +0x4d
net.(*ioSrv).ExecIO(0xc082038078, 0xc0820801e0, 0x73ab90, 0x7, 0x7e6228,
0x0, 0x0, 0x0)
D:/Go/src/pkg/net/fd_windows.go:188 +0x242
net.(*netFD).Read(0xc082080180, 0xc082070000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
D:/Go/src/pkg/net/fd_windows.go:451 +0x156
net.(*conn).Read(0xc082038060, 0xc082070000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
D:/Go/src/pkg/net/net.go:122 +0xee
net/http.(*liveSwitchReader).Read(0xc0820482a8, 0xc082070000, 0x1000,
0x1000, 0x0, 0x0, 0x0)
D:/Go/src/pkg/net/http/server.go:206 +0xb6
io.(*LimitedReader).Read(0xc0820053a0, 0xc082070000, 0x1000, 0x1000, 0x0,
0x0, 0x0)
D:/Go/src/pkg/io/io.go:399 +0xd7
bufio.(*Reader).fill(0xc08200ee40)
D:/Go/src/pkg/bufio/bufio.go:97 +0x1ba
bufio.(*Reader).ReadSlice(0xc08200ee40, 0xc08203e00a, 0x0, 0x0, 0x0, 0x0,
0x0)
D:/Go/src/pkg/bufio/bufio.go:298 +0x233
bufio.(*Reader).ReadLine(0xc08200ee40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
D:/Go/src/pkg/bufio/bufio.go:326 +0x70
net/textproto.(*Reader).readLineSlice(0xc08201ae10, 0x0, 0x0, 0x0, 0x0, 0x0)
D:/Go/src/pkg/net/textproto/reader.go:55 +0xa4
net/textproto.(*Reader).ReadLine(0xc08201ae10, 0x0, 0x0, 0x0, 0x0)
D:/Go/src/pkg/net/textproto/reader.go:36 +0x55
net/http.ReadRequest(0xc08200ee40, 0xc08201ef70, 0x0, 0x0)
D:/Go/src/pkg/net/http/request.go:556 +0xce
net/http.(*conn).readRequest(0xc082048280, 0x0, 0x0, 0x0)
D:/Go/src/pkg/net/http/server.go:577 +0x27d
net/http.(*conn).serve(0xc082048280)
D:/Go/src/pkg/net/http/server.go:1132 +0x625
created by net/http.(*Server).Serve
D:/Go/src/pkg/net/http/server.go:1721 +0x31a
goroutine 33 [chan receive, 6 minutes]:
net/http.(*persistConn).readLoop(0xc08203e420)
D:/Go/src/pkg/net/http/transport.go:798 +0x312
created by net/http.(*Transport).dialConn
D:/Go/src/pkg/net/http/transport.go:600 +0x946
goroutine 39 [chan receive, 3 minutes]:
net/http.(*persistConn).readLoop(0xc08203e6e0)
D:/Go/src/pkg/net/http/transport.go:798 +0x312
created by net/http.(*Transport).dialConn
D:/Go/src/pkg/net/http/transport.go:600 +0x946