mirror of
https://github.com/restic/restic.git
synced 2025-12-11 18:47:50 +00:00
termstatus: don't buffer stdout
There's not much use in doing so as nearly every write call was paired with a flush call. Thus, just use an unbuffered writer.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package termstatus
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -19,7 +18,7 @@ import (
|
||||
// updated. When the output is redirected to a file, the status lines are not
|
||||
// printed.
|
||||
type Terminal struct {
|
||||
wr *bufio.Writer
|
||||
wr io.Writer
|
||||
fd uintptr
|
||||
errWriter io.Writer
|
||||
msg chan message
|
||||
@@ -57,7 +56,7 @@ type fder interface {
|
||||
// are printed even if the terminal supports it.
|
||||
func New(wr io.Writer, errWriter io.Writer, disableStatus bool) *Terminal {
|
||||
t := &Terminal{
|
||||
wr: bufio.NewWriter(wr),
|
||||
wr: wr,
|
||||
errWriter: errWriter,
|
||||
msg: make(chan message),
|
||||
status: make(chan status),
|
||||
@@ -118,13 +117,6 @@ func (t *Terminal) run(ctx context.Context) {
|
||||
var dst io.Writer
|
||||
if msg.err {
|
||||
dst = t.errWriter
|
||||
|
||||
// assume t.wr and t.errWriter are different, so we need to
|
||||
// flush clearing the current line
|
||||
err := t.wr.Flush()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
||||
}
|
||||
} else {
|
||||
dst = t.wr
|
||||
}
|
||||
@@ -135,11 +127,6 @@ func (t *Terminal) run(ctx context.Context) {
|
||||
}
|
||||
|
||||
t.writeStatus(status)
|
||||
|
||||
if err := t.wr.Flush(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
||||
}
|
||||
|
||||
case stat := <-t.status:
|
||||
status = append(status[:0], stat.lines...)
|
||||
|
||||
@@ -169,26 +156,15 @@ func (t *Terminal) writeStatus(status []string) {
|
||||
for _, line := range status {
|
||||
t.clearCurrentLine(t.wr, t.fd)
|
||||
|
||||
_, err := t.wr.WriteString(line)
|
||||
_, err := t.wr.Write([]byte(line))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
||||
}
|
||||
|
||||
// flush is needed so that the current line is updated
|
||||
err = t.wr.Flush()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(status) > 0 {
|
||||
t.moveCursorUp(t.wr, t.fd, len(status)-1)
|
||||
}
|
||||
|
||||
err := t.wr.Flush()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// runWithoutStatus listens on the channels and just prints out the messages,
|
||||
@@ -199,28 +175,18 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case msg := <-t.msg:
|
||||
var flush func() error
|
||||
|
||||
var dst io.Writer
|
||||
if msg.err {
|
||||
dst = t.errWriter
|
||||
} else {
|
||||
dst = t.wr
|
||||
flush = t.wr.Flush
|
||||
}
|
||||
|
||||
if _, err := io.WriteString(dst, msg.line); err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
||||
}
|
||||
|
||||
if flush == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := flush(); err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
||||
}
|
||||
|
||||
case stat := <-t.status:
|
||||
for _, line := range stat.lines {
|
||||
// Ensure that each message ends with exactly one newline.
|
||||
@@ -228,9 +194,6 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
||||
}
|
||||
}
|
||||
if err := t.wr.Flush(); err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user