mirror of
https://github.com/clearlinux/docker.git
synced 2026-09-06 13:41:36 +00:00
Merge pull request #13966 from mountkin/fix-stats-goroutine-leak
fix the goroutine leak in the stats API if the container is not running
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/go-check/check"
|
||||
@@ -33,3 +34,38 @@ func (s *DockerSuite) TestCliStatsNoStreamGetCpu(c *check.C) {
|
||||
c.Fatalf("docker stats with no-stream get cpu usage failed: was %v", cpuPercent)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestStoppedContainerStatsGoroutines(c *check.C) {
|
||||
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "echo 1")
|
||||
id := strings.TrimSpace(out)
|
||||
|
||||
getGoRoutines := func() int {
|
||||
_, body, err := sockRequestRaw("GET", fmt.Sprintf("/info"), nil, "")
|
||||
c.Assert(err, check.IsNil)
|
||||
info := types.Info{}
|
||||
err = json.NewDecoder(body).Decode(&info)
|
||||
c.Assert(err, check.IsNil)
|
||||
body.Close()
|
||||
return info.NGoroutines
|
||||
}
|
||||
|
||||
// When the HTTP connection is closed, the number of goroutines should not increase.
|
||||
routines := getGoRoutines()
|
||||
_, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats", id), nil, "")
|
||||
c.Assert(err, check.IsNil)
|
||||
body.Close()
|
||||
|
||||
t := time.After(30 * time.Second)
|
||||
for {
|
||||
select {
|
||||
case <-t:
|
||||
c.Assert(getGoRoutines() <= routines, check.Equals, true)
|
||||
return
|
||||
default:
|
||||
if n := getGoRoutines(); n <= routines {
|
||||
return
|
||||
}
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,8 +366,8 @@ func sockRequestRaw(method, endpoint string, data io.Reader, ct string) (*http.R
|
||||
return nil, nil, fmt.Errorf("could not perform request: %v", err)
|
||||
}
|
||||
body := ioutils.NewReadCloserWrapper(resp.Body, func() error {
|
||||
defer client.Close()
|
||||
return resp.Body.Close()
|
||||
defer resp.Body.Close()
|
||||
return client.Close()
|
||||
})
|
||||
|
||||
return resp, body, nil
|
||||
|
||||
Reference in New Issue
Block a user