mirror of
https://github.com/rclone/rclone.git
synced 2025-06-25 06:23:03 +02:00
accounting: fix time to completion estimates
Previous to this change package used for this github.com/VividCortex/ewma took a 0 average to mean reset the statistics. This happens quite often when transferring files though a buffer. Replace that implementation with a simple home grown one (with about the same constant), without that feature.
This commit is contained in:
parent
842ed7d2a9
commit
ca44fb1fba
@ -7,7 +7,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VividCortex/ewma"
|
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
"github.com/ncw/rclone/fs/asyncreader"
|
"github.com/ncw/rclone/fs/asyncreader"
|
||||||
"github.com/ncw/rclone/fs/fserrors"
|
"github.com/ncw/rclone/fs/fserrors"
|
||||||
@ -37,12 +36,14 @@ type Account struct {
|
|||||||
start time.Time // Start time of first read
|
start time.Time // Start time of first read
|
||||||
lpTime time.Time // Time of last average measurement
|
lpTime time.Time // Time of last average measurement
|
||||||
lpBytes int // Number of bytes read since last measurement
|
lpBytes int // Number of bytes read since last measurement
|
||||||
avg ewma.MovingAverage // Moving average of last few measurements
|
avg float64 // Moving average of last few measurements in bytes/s
|
||||||
closed bool // set if the file is closed
|
closed bool // set if the file is closed
|
||||||
exit chan struct{} // channel that will be closed when transfer is finished
|
exit chan struct{} // channel that will be closed when transfer is finished
|
||||||
withBuf bool // is using a buffered in
|
withBuf bool // is using a buffered in
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const averagePeriod = 16 // period to do exponentially weighted averages over
|
||||||
|
|
||||||
// NewAccountSizeName makes a Account reader for an io.ReadCloser of
|
// NewAccountSizeName makes a Account reader for an io.ReadCloser of
|
||||||
// the given size and name
|
// the given size and name
|
||||||
func NewAccountSizeName(in io.ReadCloser, size int64, name string) *Account {
|
func NewAccountSizeName(in io.ReadCloser, size int64, name string) *Account {
|
||||||
@ -53,7 +54,7 @@ func NewAccountSizeName(in io.ReadCloser, size int64, name string) *Account {
|
|||||||
size: size,
|
size: size,
|
||||||
name: name,
|
name: name,
|
||||||
exit: make(chan struct{}),
|
exit: make(chan struct{}),
|
||||||
avg: ewma.NewMovingAverage(),
|
avg: 0,
|
||||||
lpTime: time.Now(),
|
lpTime: time.Now(),
|
||||||
max: int64(fs.Config.MaxTransfer),
|
max: int64(fs.Config.MaxTransfer),
|
||||||
}
|
}
|
||||||
@ -136,7 +137,7 @@ func (acc *Account) averageLoop() {
|
|||||||
// Add average of last second.
|
// Add average of last second.
|
||||||
elapsed := now.Sub(acc.lpTime).Seconds()
|
elapsed := now.Sub(acc.lpTime).Seconds()
|
||||||
avg := float64(acc.lpBytes) / elapsed
|
avg := float64(acc.lpBytes) / elapsed
|
||||||
acc.avg.Add(avg)
|
acc.avg = (avg + (averagePeriod-1)*acc.avg) / averagePeriod
|
||||||
acc.lpBytes = 0
|
acc.lpBytes = 0
|
||||||
acc.lpTime = now
|
acc.lpTime = now
|
||||||
// Unlock stats
|
// Unlock stats
|
||||||
@ -221,7 +222,7 @@ func (acc *Account) speed() (bps, current float64) {
|
|||||||
// Calculate speed from first read.
|
// Calculate speed from first read.
|
||||||
total := float64(time.Now().Sub(acc.start)) / float64(time.Second)
|
total := float64(time.Now().Sub(acc.start)) / float64(time.Second)
|
||||||
bps = float64(acc.bytes) / total
|
bps = float64(acc.bytes) / total
|
||||||
current = acc.avg.Value()
|
current = acc.avg
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,13 +242,13 @@ func (acc *Account) eta() (eta time.Duration, ok bool) {
|
|||||||
if left <= 0 {
|
if left <= 0 {
|
||||||
return 0, true
|
return 0, true
|
||||||
}
|
}
|
||||||
avg := acc.avg.Value()
|
avg := acc.avg
|
||||||
if avg <= 0 {
|
if avg <= 0 {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
seconds := float64(left) / acc.avg.Value()
|
seconds := float64(left) / avg
|
||||||
|
|
||||||
return time.Duration(time.Second * time.Duration(int(seconds))), true
|
return time.Second * time.Duration(seconds), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// String produces stats for this file
|
// String produces stats for this file
|
||||||
|
Loading…
x
Reference in New Issue
Block a user