@@ -251,8 +251,9 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions)
251251 }
252252 }
253253
254- // We don't expect any asynchronous errors: closeChan can be closed.
254+ // We don't expect any asynchronous errors: closeChan can be closed and disabled .
255255 close (closeChan )
256+ closeChan = nil
256257
257258 // make sure each container get at least one valid stat data
258259 waitFirst .Wait ()
@@ -288,63 +289,55 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions)
288289 Format : NewStatsFormat (format , daemonOSType ),
289290 }
290291
291- var err error
292292 ticker := time .NewTicker (500 * time .Millisecond )
293293 defer ticker .Stop ()
294- for range ticker .C {
295- var ccStats []StatsEntry
296- cStats .mu .RLock ()
297- for _ , c := range cStats .cs {
298- ccStats = append (ccStats , c .GetStatistics ())
299- }
300- cStats .mu .RUnlock ()
301-
302- if ! options .NoStream {
303- // Start by moving the cursor to the top-left
304- _ , _ = fmt .Fprint (& statsTextBuffer , "\033 [H" )
305- }
294+ for {
295+ select {
296+ case <- ticker .C :
297+ cStats .mu .RLock ()
298+ ccStats := make ([]StatsEntry , 0 , len (cStats .cs ))
299+ for _ , c := range cStats .cs {
300+ ccStats = append (ccStats , c .GetStatistics ())
301+ }
302+ cStats .mu .RUnlock ()
306303
307- if err = statsFormatWrite (statsCtx , ccStats , daemonOSType , ! options .NoTrunc ); err != nil {
308- break
309- }
304+ if ! options .NoStream {
305+ // Start by moving the cursor to the top-left
306+ _ , _ = fmt .Fprint (& statsTextBuffer , "\033 [H" )
307+ }
310308
311- if ! options .NoStream {
312- for _ , line := range strings .Split (statsTextBuffer .String (), "\n " ) {
313- // In case the new text is shorter than the one we are writing over,
314- // we'll append the "erase line" escape sequence to clear the remaining text.
315- _ , _ = fmt .Fprintln (& statsTextBuffer , line , "\033 [K" )
309+ if err := statsFormatWrite (statsCtx , ccStats , daemonOSType , ! options .NoTrunc ); err != nil {
310+ return err
316311 }
317312
318- // We might have fewer containers than before, so let's clear the remaining text
319- _ , _ = fmt .Fprint (& statsTextBuffer , "\033 [J" )
320- }
313+ if ! options .NoStream {
314+ for _ , line := range strings .Split (statsTextBuffer .String (), "\n " ) {
315+ // In case the new text is shorter than the one we are writing over,
316+ // we'll append the "erase line" escape sequence to clear the remaining text.
317+ _ , _ = fmt .Fprintln (& statsTextBuffer , line , "\033 [K" )
318+ }
319+ // We might have fewer containers than before, so let's clear the remaining text
320+ _ , _ = fmt .Fprint (& statsTextBuffer , "\033 [J" )
321+ }
321322
322- _ , _ = fmt .Fprint (dockerCLI .Out (), statsTextBuffer .String ())
323- statsTextBuffer .Reset ()
323+ _ , _ = fmt .Fprint (dockerCLI .Out (), statsTextBuffer .String ())
324+ statsTextBuffer .Reset ()
324325
325- if len (cStats .cs ) == 0 && ! showAll {
326- break
327- }
328- if options .NoStream {
329- break
330- }
331- select {
326+ if len (ccStats ) == 0 && ! showAll {
327+ return nil
328+ }
329+ if options .NoStream {
330+ return nil
331+ }
332332 case err , ok := <- closeChan :
333- if ok {
334- if err != nil {
335- // Suppress "unexpected EOF" errors in the CLI so that
336- // it shuts down cleanly when the daemon restarts.
337- if errors .Is (err , io .ErrUnexpectedEOF ) {
338- return nil
339- }
340- return err
341- }
333+ if ! ok || err == nil || errors .Is (err , io .ErrUnexpectedEOF ) {
334+ // Suppress "unexpected EOF" errors in the CLI so that
335+ // it shuts down cleanly when the daemon restarts.
336+ return nil
342337 }
343- default :
344- // just skip
338+ return err
345339 }
346340 }
347- return err
348341}
349342
350343// newEventHandler initializes and returns an eventHandler
0 commit comments