Optimise `docker stats` to not require clearing the whole screen

Instead of clearing the whole screen and then writing the new stats,
we now write the new stats on top of the old text, and then clear
the remaining text.

This is a more efficient way to update the stats, as it avoids the
flickering that happens when the screen is cleared and rewritten.

Signed-off-by: Giedrius Jonikas <giedriusj1@gmail.com>
(cherry picked from commit cb2f95ceee)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Giedrius Jonikas 2024-11-16 15:29:57 +00:00 committed by Sebastiaan van Stijn
parent c6537362af
commit 39d73afbdd
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
1 changed files with 13 additions and 3 deletions

View File

@ -287,16 +287,26 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions)
cStats.mu.RUnlock() cStats.mu.RUnlock()
if !options.NoStream { if !options.NoStream {
// Start by clearing the screen and moving the cursor to the top-left // Start by moving the cursor to the top-left
_, _ = fmt.Fprint(&statsTextBuffer, "\033[2J\033[H") _, _ = fmt.Fprint(&statsTextBuffer, "\033[H")
} }
if err = statsFormatWrite(statsCtx, ccStats, daemonOSType, !options.NoTrunc); err != nil { if err = statsFormatWrite(statsCtx, ccStats, daemonOSType, !options.NoTrunc); err != nil {
break break
} }
_, _ = fmt.Fprint(dockerCLI.Out(), statsTextBuffer.String()) 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.Fprint(&statsTextBuffer, line, "\033[K\n")
}
// 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() statsTextBuffer.Reset()
if len(cStats.cs) == 0 && !showAll { if len(cStats.cs) == 0 && !showAll {