vbauerster / mpb

multi progress bar for Go cli applications
The Unlicense
2.31k stars 123 forks source link

decor.ETA is extremely inaccurate #20

Closed Naatan closed 6 years ago

Naatan commented 6 years ago

Use the following sample code:

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "path/filepath"
    "sync"

    "github.com/vbauerster/mpb"
    "github.com/vbauerster/mpb/decor"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(3)
    p := mpb.New(mpb.WithWaitGroup(&wg), mpb.WithWidth(64))
    go download(p, &wg)
    go download(p, &wg)
    go download(p, &wg)

    wg.Wait()
    p.Wait() // if you omit this line, rendering bars goroutine will quit early
    fmt.Println("done")
}

func download(p *mpb.Progress, wg *sync.WaitGroup) {
    defer wg.Done()

    url := "http://ipv4.download.thinkbroadband.com/512MB.zip"

    resp, err := http.Get(url)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        fmt.Printf("Server return non-200 status: %s\n", resp.Status)
        return
    }

    size := resp.ContentLength

    // create dest
    destName := filepath.Base(url)
    dest, err := os.Create(destName)
    if err != nil {
        fmt.Printf("Can't create %s: %v\n", destName, err)
        return
    }
    defer dest.Close()

    bar := p.AddBar(size,
        mpb.PrependDecorators(
            decor.CountersKibiByte("% 6.1f / % 6.1f", 18, 0)),
        mpb.AppendDecorators(decor.ETA(0, decor.DwidthSync)))

    // create proxy reader
    reader := bar.ProxyReader(resp.Body)

    // and copy from reader, ignoring errors
    io.Copy(dest, reader)

    fmt.Printf("Downloaded")
}

Note the ETA's on the downloads are jumping up and down all over the place, they do not settle down as time goes on. In my actual use-case they actually run down to 0 in the first 50% and then remain there, I'm not sure how to get that to reproduce though.

vbauerster commented 6 years ago

To tune eta, you can play with BarEtaAlpha option and maybe reduce refresh rate. This recording was made with BarEtaAlpha set to 0.1 and refresh rate to set 300 ms. If it is still not satisfactory, you can implement your own eta decorator, see decor package for example.

vbauerster commented 6 years ago

Can you please update to commit 8272499, and check one more time? If fluctuations are high, I do recommend setting BarEtaAlpha to something like 0.1 or even to 0.04.