mirror of https://github.com/docker/cli.git
Buffer 'docker stats' text to avoid terminal flickering
This change reduces the flickering of the terminal when running `docker stats` by buffering the formatted stats text and printing it in one write. Should also consume less CPU as we now only have to issue a single syscall to write the stats text to the terminal. Signed-off-by: Giedrius Jonikas <giedriusj1@gmail.com>
This commit is contained in:
parent
aa331e94cc
commit
0b16070ae6
|
@ -1,6 +1,7 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -264,31 +265,40 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions)
|
||||||
// so we unlikely hit this code in practice.
|
// so we unlikely hit this code in practice.
|
||||||
daemonOSType = dockerCLI.ServerInfo().OSType
|
daemonOSType = dockerCLI.ServerInfo().OSType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Buffer to store formatted stats text.
|
||||||
|
// Once formatted, it will be printed in one write to avoid screen flickering.
|
||||||
|
var statsTextBuffer bytes.Buffer
|
||||||
|
|
||||||
statsCtx := formatter.Context{
|
statsCtx := formatter.Context{
|
||||||
Output: dockerCLI.Out(),
|
Output: &statsTextBuffer,
|
||||||
Format: NewStatsFormat(format, daemonOSType),
|
Format: NewStatsFormat(format, daemonOSType),
|
||||||
}
|
}
|
||||||
cleanScreen := func() {
|
|
||||||
if !options.NoStream {
|
|
||||||
_, _ = fmt.Fprint(dockerCLI.Out(), "\033[2J")
|
|
||||||
_, _ = fmt.Fprint(dockerCLI.Out(), "\033[H")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
ticker := time.NewTicker(500 * time.Millisecond)
|
ticker := time.NewTicker(500 * time.Millisecond)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
cleanScreen()
|
|
||||||
var ccStats []StatsEntry
|
var ccStats []StatsEntry
|
||||||
cStats.mu.RLock()
|
cStats.mu.RLock()
|
||||||
for _, c := range cStats.cs {
|
for _, c := range cStats.cs {
|
||||||
ccStats = append(ccStats, c.GetStatistics())
|
ccStats = append(ccStats, c.GetStatistics())
|
||||||
}
|
}
|
||||||
cStats.mu.RUnlock()
|
cStats.mu.RUnlock()
|
||||||
|
|
||||||
|
if !options.NoStream {
|
||||||
|
// Start by clearing the screen and moving the cursor to the top-left
|
||||||
|
_, _ = fmt.Fprint(&statsTextBuffer, "\033[2J\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())
|
||||||
|
|
||||||
|
statsTextBuffer.Reset()
|
||||||
|
|
||||||
if len(cStats.cs) == 0 && !showAll {
|
if len(cStats.cs) == 0 && !showAll {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue