Send fetch progress at most once per second (closes #206)
check / check (push) Waiting to run
check / check (push) Waiting to run
progressWriter sent an update for every chunk io.Copy wrote, so fetch logged a line per 32 KiB. It now sends at most one per second, waiting a second before the first as gen and check do, and one more when the last byte is written. TestFetchProgress now checks that a download of several chunks sends no more than one update per second plus the last. Model: opus-5-5
This commit was merged in pull request #215.
This commit is contained in:
+24
-14
@@ -679,21 +679,26 @@ func resolveManifestURL(inputURL string) (string, error) {
|
||||
return parsed.JoinPath(defaultManifestName).String(), nil
|
||||
}
|
||||
|
||||
// progressWriter wraps an io.Writer and reports progress to a channel.
|
||||
// progressWriter wraps an io.Writer and reports progress to a channel,
|
||||
// at most once per second and once more when the last byte is written.
|
||||
type progressWriter struct {
|
||||
w io.Writer
|
||||
path string
|
||||
total int64
|
||||
written int64
|
||||
startTime time.Time
|
||||
progress chan<- DownloadProgress
|
||||
w io.Writer
|
||||
path string
|
||||
total int64
|
||||
written int64
|
||||
startTime time.Time
|
||||
lastProgress time.Time
|
||||
progress chan<- DownloadProgress
|
||||
}
|
||||
|
||||
func (pw *progressWriter) Write(p []byte) (int, error) {
|
||||
n, err := pw.w.Write(p)
|
||||
|
||||
pw.written += int64(n)
|
||||
if pw.progress != nil {
|
||||
|
||||
isLast := pw.written == pw.total
|
||||
if pw.progress != nil &&
|
||||
(isLast || time.Since(pw.lastProgress) >= time.Second) {
|
||||
var (
|
||||
bytesPerSec float64
|
||||
eta time.Duration
|
||||
@@ -715,6 +720,8 @@ func (pw *progressWriter) Write(p []byte) (int, error) {
|
||||
BytesPerSec: bytesPerSec,
|
||||
ETA: eta,
|
||||
})
|
||||
|
||||
pw.lastProgress = time.Now()
|
||||
}
|
||||
|
||||
return n, err
|
||||
@@ -899,13 +906,16 @@ func saveResponse(
|
||||
// Set up hash computation
|
||||
h := sha256.New()
|
||||
|
||||
// Create progress-reporting writer that also computes hash
|
||||
// Create progress-reporting writer that also computes hash. The first
|
||||
// update waits a second, as gen's and check's do.
|
||||
start := time.Now()
|
||||
pw := &progressWriter{
|
||||
w: io.MultiWriter(out, h),
|
||||
path: localPath,
|
||||
total: totalBytes,
|
||||
startTime: time.Now(),
|
||||
progress: progress,
|
||||
w: io.MultiWriter(out, h),
|
||||
path: localPath,
|
||||
total: totalBytes,
|
||||
startTime: start,
|
||||
lastProgress: start,
|
||||
progress: progress,
|
||||
}
|
||||
|
||||
// Copy content while hashing and reporting progress. One byte past
|
||||
|
||||
Reference in New Issue
Block a user