Skip to content

Commit aed3172

Browse files
committed
print download progress and speed
1 parent f4aa210 commit aed3172

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed

download.go

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import (
88
"net/http"
99
"os"
1010
"path/filepath"
11+
"sync/atomic"
1112
"time"
13+
14+
"github.com/cenkalti/log"
15+
"github.com/paulbellamy/ratecounter"
1216
)
1317

1418
type Download struct {
@@ -99,8 +103,11 @@ func (d *Download) Run(ctx context.Context) error {
99103
trw := &TimerResetWriter{timer: time.AfterFunc(defaultTimeout, cancel)}
100104
tr := io.TeeReader(rc, trw)
101105

106+
pr := NewProgressReader(tr, d.state.Offset, d.state.Size, d.String())
107+
go pr.Run()
102108
remaining := d.state.Size - d.state.Offset
103-
n, copyErr := io.CopyN(wc, tr, remaining)
109+
n, copyErr := io.CopyN(wc, pr, remaining)
110+
pr.Close()
104111

105112
err = wc.Close()
106113
if err != nil {
@@ -167,3 +174,48 @@ func (w *TimerResetWriter) Write(p []byte) (int, error) {
167174
w.timer.Reset(defaultTimeout)
168175
return len(p), nil
169176
}
177+
178+
type ProgressReader struct {
179+
r io.Reader
180+
offset int64
181+
size int64
182+
prefix string
183+
counter *ratecounter.RateCounter
184+
closeC chan struct{}
185+
}
186+
187+
func NewProgressReader(r io.Reader, offset, size int64, prefix string) *ProgressReader {
188+
return &ProgressReader{
189+
r: r,
190+
offset: offset,
191+
size: size,
192+
prefix: prefix,
193+
counter: ratecounter.NewRateCounter(time.Second),
194+
closeC: make(chan struct{}),
195+
}
196+
}
197+
198+
func (r *ProgressReader) Read(p []byte) (int, error) {
199+
n, err := r.r.Read(p)
200+
r.counter.Incr(int64(n))
201+
atomic.AddInt64(&r.offset, int64(n))
202+
return n, err
203+
}
204+
205+
func (r *ProgressReader) Run() {
206+
for {
207+
select {
208+
case <-time.After(time.Second): // TODO use time.Ticker
209+
offset := atomic.LoadInt64(&r.offset)
210+
progress := (offset * 100) / r.size
211+
speed := r.counter.Rate() / 1024
212+
log.Infof("%s %d%% %dKB/s", r.prefix, progress, speed)
213+
case <-r.closeC:
214+
return
215+
}
216+
}
217+
}
218+
219+
func (r *ProgressReader) Close() {
220+
close(r.closeC)
221+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/BurntSushi/toml v0.3.1
77
github.com/adrg/xdg v0.2.1
88
github.com/cenkalti/log v1.0.0
9+
github.com/paulbellamy/ratecounter v0.2.0
910
github.com/putdotio/go-putio v1.3.2
1011
github.com/stretchr/testify v1.6.1 // indirect
1112
go.etcd.io/bbolt v1.3.5

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g
1515
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
1616
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
1717
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
18+
github.com/paulbellamy/ratecounter v0.2.0 h1:2L/RhJq+HA8gBQImDXtLPrDXK5qAj6ozWVK/zFXVJGs=
19+
github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
1820
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1921
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2022
github.com/putdotio/go-putio v1.3.2 h1:PZeVe9ckULim99J+zMDlQ6Lq+iv8/vJM4EMGrXfPAY4=

main.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
var Version = "0.0.0"
2121

2222
// TODO Reconciliation tests
23-
// TODO Measure download progress
2423
// TODO Measure upload progress
2524
// TODO Daemon mode
2625
// TODO HTTP API

0 commit comments

Comments
 (0)