mirror of
https://github.com/restic/restic.git
synced 2025-12-12 05:11:46 +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
|
package termstatus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -19,7 +18,7 @@ import (
|
|||||||
// updated. When the output is redirected to a file, the status lines are not
|
// updated. When the output is redirected to a file, the status lines are not
|
||||||
// printed.
|
// printed.
|
||||||
type Terminal struct {
|
type Terminal struct {
|
||||||
wr *bufio.Writer
|
wr io.Writer
|
||||||
fd uintptr
|
fd uintptr
|
||||||
errWriter io.Writer
|
errWriter io.Writer
|
||||||
msg chan message
|
msg chan message
|
||||||
@@ -57,7 +56,7 @@ type fder interface {
|
|||||||
// are printed even if the terminal supports it.
|
// are printed even if the terminal supports it.
|
||||||
func New(wr io.Writer, errWriter io.Writer, disableStatus bool) *Terminal {
|
func New(wr io.Writer, errWriter io.Writer, disableStatus bool) *Terminal {
|
||||||
t := &Terminal{
|
t := &Terminal{
|
||||||
wr: bufio.NewWriter(wr),
|
wr: wr,
|
||||||
errWriter: errWriter,
|
errWriter: errWriter,
|
||||||
msg: make(chan message),
|
msg: make(chan message),
|
||||||
status: make(chan status),
|
status: make(chan status),
|
||||||
@@ -118,13 +117,6 @@ func (t *Terminal) run(ctx context.Context) {
|
|||||||
var dst io.Writer
|
var dst io.Writer
|
||||||
if msg.err {
|
if msg.err {
|
||||||
dst = t.errWriter
|
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 {
|
} else {
|
||||||
dst = t.wr
|
dst = t.wr
|
||||||
}
|
}
|
||||||
@@ -135,11 +127,6 @@ func (t *Terminal) run(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.writeStatus(status)
|
t.writeStatus(status)
|
||||||
|
|
||||||
if err := t.wr.Flush(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
case stat := <-t.status:
|
case stat := <-t.status:
|
||||||
status = append(status[:0], stat.lines...)
|
status = append(status[:0], stat.lines...)
|
||||||
|
|
||||||
@@ -169,26 +156,15 @@ func (t *Terminal) writeStatus(status []string) {
|
|||||||
for _, line := range status {
|
for _, line := range status {
|
||||||
t.clearCurrentLine(t.wr, t.fd)
|
t.clearCurrentLine(t.wr, t.fd)
|
||||||
|
|
||||||
_, err := t.wr.WriteString(line)
|
_, err := t.wr.Write([]byte(line))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
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 {
|
if len(status) > 0 {
|
||||||
t.moveCursorUp(t.wr, t.fd, len(status)-1)
|
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,
|
// 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():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case msg := <-t.msg:
|
case msg := <-t.msg:
|
||||||
var flush func() error
|
|
||||||
|
|
||||||
var dst io.Writer
|
var dst io.Writer
|
||||||
if msg.err {
|
if msg.err {
|
||||||
dst = t.errWriter
|
dst = t.errWriter
|
||||||
} else {
|
} else {
|
||||||
dst = t.wr
|
dst = t.wr
|
||||||
flush = t.wr.Flush
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := io.WriteString(dst, msg.line); err != nil {
|
if _, err := io.WriteString(dst, msg.line); err != nil {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
_, _ = 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:
|
case stat := <-t.status:
|
||||||
for _, line := range stat.lines {
|
for _, line := range stat.lines {
|
||||||
// Ensure that each message ends with exactly one newline.
|
// 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)
|
_, _ = 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