moby--moby/utils/progressreader.go

56 lines
1.5 KiB
Go
Raw Normal View History

2013-11-28 20:16:57 +00:00
package utils
import (
"io"
2013-11-28 20:37:07 +00:00
"time"
2013-11-28 20:16:57 +00:00
)
// Reader with progress bar
type progressReader struct {
2013-12-19 20:32:58 +00:00
reader io.ReadCloser // Stream to read from
output io.Writer // Where to send progress bar to
progress JSONProgress
2013-11-28 20:16:57 +00:00
lastUpdate int // How many bytes read at least update
ID string
action string
2013-12-19 20:32:58 +00:00
sf *StreamFormatter
newLine bool
2013-11-28 20:16:57 +00:00
}
func (r *progressReader) Read(p []byte) (n int, err error) {
2013-12-19 20:32:58 +00:00
read, err := r.reader.Read(p)
2013-11-28 20:16:57 +00:00
r.progress.Current += read
updateEvery := 1024 * 512 //512kB
if r.progress.Total > 0 {
// Update progress for every 1% read if 1% < 512kB
if increment := int(0.01 * float64(r.progress.Total)); increment < updateEvery {
updateEvery = increment
}
}
if r.progress.Current-r.lastUpdate > updateEvery || err != nil {
r.output.Write(r.sf.FormatProgress(r.ID, r.action, &r.progress))
r.lastUpdate = r.progress.Current
}
// Send newline when complete
if r.newLine && err != nil {
r.output.Write(r.sf.FormatStatus("", ""))
}
return read, err
}
func (r *progressReader) Close() error {
2013-12-19 20:32:58 +00:00
r.progress.Current = r.progress.Total
r.output.Write(r.sf.FormatProgress(r.ID, r.action, &r.progress))
return r.reader.Close()
2013-11-28 20:16:57 +00:00
}
func ProgressReader(r io.ReadCloser, size int, output io.Writer, sf *StreamFormatter, newline bool, ID, action string) *progressReader {
return &progressReader{
reader: r,
output: NewWriteFlusher(output),
ID: ID,
action: action,
2013-11-28 20:37:07 +00:00
progress: JSONProgress{Total: size, Start: time.Now().UTC().Unix()},
2013-11-28 20:16:57 +00:00
sf: sf,
newLine: newline,
}
}