From 292001a451430113c91a0a67ed8451812304e72b Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 28 Oct 2025 11:59:38 +0100 Subject: [PATCH] cli/command/container: RunStats: early return for non-streaming We should consider splitting this out to a separate function, but start with just an early return before we hit the timer-loop. Signed-off-by: Sebastiaan van Stijn --- cli/command/container/stats.go | 41 +++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/cli/command/container/stats.go b/cli/command/container/stats.go index 222e5eb2e7..84ca3d72d4 100644 --- a/cli/command/container/stats.go +++ b/cli/command/container/stats.go @@ -298,6 +298,24 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions) Format: NewStatsFormat(format, daemonOSType), } + if options.NoStream { + cStats.mu.RLock() + ccStats := make([]StatsEntry, 0, len(cStats.cs)) + for _, c := range cStats.cs { + ccStats = append(ccStats, c.GetStatistics()) + } + cStats.mu.RUnlock() + + if len(ccStats) == 0 { + return nil + } + if err := statsFormatWrite(statsCtx, ccStats, daemonOSType, !options.NoTrunc); err != nil { + return err + } + _, _ = fmt.Fprint(dockerCLI.Out(), statsTextBuffer.String()) + return nil + } + ticker := time.NewTicker(500 * time.Millisecond) defer ticker.Stop() for { @@ -310,24 +328,20 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions) } cStats.mu.RUnlock() - if !options.NoStream { - // Start by moving the cursor to the top-left - _, _ = fmt.Fprint(&statsTextBuffer, "\033[H") - } + // Start by moving the cursor to the top-left + _, _ = fmt.Fprint(&statsTextBuffer, "\033[H") if err := statsFormatWrite(statsCtx, ccStats, daemonOSType, !options.NoTrunc); err != nil { return err } - if !options.NoStream { - for _, line := range strings.Split(statsTextBuffer.String(), "\n") { - // In case the new text is shorter than the one we are writing over, - // we'll append the "erase line" escape sequence to clear the remaining text. - _, _ = fmt.Fprintln(&statsTextBuffer, line, "\033[K") - } - // We might have fewer containers than before, so let's clear the remaining text - _, _ = fmt.Fprint(&statsTextBuffer, "\033[J") + for _, line := range strings.Split(statsTextBuffer.String(), "\n") { + // In case the new text is shorter than the one we are writing over, + // we'll append the "erase line" escape sequence to clear the remaining text. + _, _ = fmt.Fprintln(&statsTextBuffer, line, "\033[K") } + // We might have fewer containers than before, so let's clear the remaining text + _, _ = fmt.Fprint(&statsTextBuffer, "\033[J") _, _ = fmt.Fprint(dockerCLI.Out(), statsTextBuffer.String()) statsTextBuffer.Reset() @@ -335,9 +349,6 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions) if len(ccStats) == 0 && !showAll { return nil } - if options.NoStream { - return nil - } case err, ok := <-closeChan: if !ok || err == nil || errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { // Suppress "unexpected EOF" errors in the CLI so that