From d4738db561bd5d9a353cc262f439fad9a9f88b46 Mon Sep 17 00:00:00 2001 From: Hu Keping Date: Thu, 9 Jul 2015 04:17:53 +0800 Subject: [PATCH] Fix connection block when using docker stats API For now CLI `docker stats` will not block even if the container was not running is because there is a 2s timeout setting when waiting for the response. I think why we hang there waiting for the container to run is because we want to get the stats of container immediately when it starts running. But it will block when use the API directly, for example - curl - Google Chrome plugin, Postman - Firefox plugin, RESTClient This patch keeps the feature that getting info immediately when container starts running and in the meantime, it will not block when using the API directrly. Signed-off-by: Hu Keping Upstream-commit: d9bf8163ad8579cf2ab9f55925f9ea5037e5b525 Component: engine --- components/engine/api/client/stats.go | 12 +++++++++--- components/engine/api/server/container.go | 10 ++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/components/engine/api/client/stats.go b/components/engine/api/client/stats.go index b79d3a5f3f..06ec3039df 100644 --- a/components/engine/api/client/stats.go +++ b/components/engine/api/client/stats.go @@ -61,10 +61,16 @@ func (s *containerStats) Collect(cli *DockerCli, streamStats bool) { u <- err return } - var ( + + var memPercent = 0.0 + var cpuPercent = 0.0 + + // MemoryStats.Limit will never be 0 unless the container is not running and we havn't + // got any data from cgroup + if v.MemoryStats.Limit != 0 { memPercent = float64(v.MemoryStats.Usage) / float64(v.MemoryStats.Limit) * 100.0 - cpuPercent = 0.0 - ) + } + previousCPU = v.PreCPUStats.CPUUsage.TotalUsage previousSystem = v.PreCPUStats.SystemUsage cpuPercent = calculateCPUPercent(previousCPU, previousSystem, v) diff --git a/components/engine/api/server/container.go b/components/engine/api/server/container.go index 6699b0f876..468fe55605 100644 --- a/components/engine/api/server/container.go +++ b/components/engine/api/server/container.go @@ -74,6 +74,16 @@ func (s *Server) getContainersStats(version version.Version, w http.ResponseWrit } stream := boolValueOrDefault(r, "stream", true) + + // If the container is not running and requires no stream, return an empty stats. + container, err := s.daemon.Get(vars["name"]) + if err != nil { + return err + } + if !container.IsRunning() && !stream { + return writeJSON(w, http.StatusOK, &types.Stats{}) + } + var out io.Writer if !stream { w.Header().Set("Content-Type", "application/json")