Improve the ETA displayed during backup
The ETA restic displays was based on a rate computed across the entire backup operation. Often restic can progress at uneven rates. In the worst case, restic progresses over most of the backup at a very high rate and then finds new data to back up. The displayed ETA is then unrealistic and never adapts. Restic now estimates the transfer rate based on a sliding window, with the goal of adapting to observed changes in rate. To avoid wild changes in the estimate, several heuristics are used to keep the sliding window wide enough to be relatively stable.
This commit is contained in:
parent
e14ccb1142
commit
0372c7ef04
4 changed files with 359 additions and 4 deletions
|
@ -43,7 +43,8 @@ type Progress struct {
|
|||
progress.Updater
|
||||
mu sync.Mutex
|
||||
|
||||
start time.Time
|
||||
start time.Time
|
||||
estimator rateEstimator
|
||||
|
||||
scanStarted, scanFinished bool
|
||||
|
||||
|
@ -60,6 +61,7 @@ func NewProgress(printer ProgressPrinter, interval time.Duration) *Progress {
|
|||
start: time.Now(),
|
||||
currentFiles: make(map[string]struct{}),
|
||||
printer: printer,
|
||||
estimator: *newRateEstimator(time.Now()),
|
||||
}
|
||||
p.Updater = *progress.NewUpdater(interval, func(runtime time.Duration, final bool) {
|
||||
if final {
|
||||
|
@ -73,9 +75,13 @@ func NewProgress(printer ProgressPrinter, interval time.Duration) *Progress {
|
|||
|
||||
var secondsRemaining uint64
|
||||
if p.scanFinished {
|
||||
secs := float64(runtime / time.Second)
|
||||
todo := float64(p.total.Bytes - p.processed.Bytes)
|
||||
secondsRemaining = uint64(secs / float64(p.processed.Bytes) * todo)
|
||||
rate := p.estimator.rate(time.Now())
|
||||
if rate <= 0 {
|
||||
secondsRemaining = 0
|
||||
} else {
|
||||
todo := float64(p.total.Bytes - p.processed.Bytes)
|
||||
secondsRemaining = uint64(todo / rate)
|
||||
}
|
||||
}
|
||||
|
||||
p.printer.Update(p.total, p.processed, p.errors, p.currentFiles, p.start, secondsRemaining)
|
||||
|
@ -105,6 +111,7 @@ func (p *Progress) addProcessed(c Counter) {
|
|||
p.processed.Files += c.Files
|
||||
p.processed.Dirs += c.Dirs
|
||||
p.processed.Bytes += c.Bytes
|
||||
p.estimator.recordBytes(time.Now(), c.Bytes)
|
||||
p.scanStarted = true
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue