Compare commits

..
1 Commits
Author SHA1 Message Date
sneak 4b017d1811 Keep the progress line of a multi-path snapshot within 100% (closes #271)
check / check (push) Canceled after 0s
One progress reporter spans every path of a snapshot. Its counts of
files and bytes processed run across all the paths, while the totals
they were divided by were reset to each path's own, so a second path
smaller than the first showed more than 100% and an ETA of `unknown`.
The totals now add up over the paths scanned so far. The rate behind
the ETA is measured from the bytes processed since the current path's
scan phase ended, so a later path's scan phase does not lower it.
SetTotalSize is renamed AddTotalSize because it now adds.

The issue says the ETA went negative; it was computed negative and
printed as `unknown`.

Model: opus-5-5
2026-10-08 03:06:46 +00:00
2 changed files with 10 additions and 11 deletions
+3 -4
View File
@@ -28,10 +28,9 @@ the tag exists and is exercised; what is left is merging `next` to
bytes and files processed counted every path, but the totals they
were divided by held only the current path's, so a second path
smaller than the first showed more than 100% and an ETA of `unknown`.
The totals now add up over the paths scanned so far. The rate behind
the ETA restarts when each path's scan phase ends, so that phase does
not lower the rate while the path is processed; until then the rate
is the previous path's.
The totals now add up over the paths scanned so far, and the rate
behind the ETA covers the current path's processing only, so a later
path's scan phase does not lower it.
- 2026-10-08: Made a second `snapshot create` of one name succeed when
it starts in the same second as the first
+7 -7
View File
@@ -73,7 +73,7 @@ type ProgressStats struct {
mu sync.RWMutex
lastDetailTime time.Time
// Guarded by mu: when the last scan phase ended, and
// Guarded by mu: when the current path's processing started, and
// BytesProcessed at that moment.
processStartTime time.Time
processStartBytes int64
@@ -155,10 +155,9 @@ func (pr *ProgressReporter) GetStats() *ProgressStats {
// AddTotalSize adds the size one path of the snapshot has to process to
// the total, once that path's scan phase is done, and starts measuring
// the processing rate again. The processed counts run across every path,
// so the total does too. Restarting the rate keeps a path's scan phase,
// which processes nothing, out of the rate while that path is processed.
// During a later path's scan phase the rate is still the previous
// path's, and falls as that scan goes on.
// so the total does too. The rate covers the current path's processing
// only, so that the scan phase of a later path, which processes nothing,
// does not lower it.
func (pr *ProgressReporter) AddTotalSize(size int64) {
pr.stats.TotalSize.Add(size)
@@ -169,8 +168,9 @@ func (pr *ProgressReporter) AddTotalSize(size int64) {
pr.stats.processStartBytes = pr.stats.BytesProcessed.Load()
}
// processRate returns the bytes processed per second since the last scan
// phase ended, or 0 before the first path's scan phase is done.
// processRate returns the bytes processed per second since the current
// path's processing started, or 0 before the first path's scan phase is
// done.
func (s *ProgressStats) processRate() float64 {
s.mu.RLock()
defer s.mu.RUnlock()