Przeglądaj źródła

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 <hukeping@huawei.com>
Hu Keping 10 lat temu
rodzic
commit
d9bf8163ad
2 zmienionych plików z 19 dodań i 3 usunięć
  1. 9 3
      api/client/stats.go
  2. 10 0
      api/server/container.go

+ 9 - 3
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)

+ 10 - 0
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")