package mget import ( "fmt" "github.com/vbauerster/mpb/v8" "github.com/vbauerster/mpb/v8/decor" "io" "strings" "time" ) func (m *Mget) processMiddleware(base mpb.BarFiller) mpb.BarFiller { fn := func(w io.Writer, st decor.Statistics) error { var res string count := 0 fmt.Fprintf(w, "\nSpeed:%v AvgSpeed:%v\n", m.Redo.FormatSpeed("MB"), m.Redo.FormatAvgSpeed("MB")) _, err := fmt.Fprintf(w, "Finished:%s Total Write:%d\n\n", m.Redo.FormatPercent(), m.Redo.Total()) for k := range m.threads { v := m.threads[len(m.threads)-1-k] if v != nil { count++ percent := v.FormatPercent() if m.Redo.Total() == m.Redo.ContentLength { percent = "100.00%" } res = fmt.Sprintf("Thread %v: %s %s\t", len(m.threads)-k, v.FormatSpeed("MB"), percent) + res if count%3 == 0 { res = strings.TrimRight(res, "\t") fmt.Fprintf(w, "%s\n", res) res = "" } } } if res != "" { res = strings.TrimRight(res, "\t") fmt.Fprintf(w, "%s\n", res) } return err } if base == nil { return mpb.BarFillerFunc(fn) } return mpb.BarFillerFunc(func(w io.Writer, st decor.Statistics) error { err := fn(w, st) if err != nil { return err } return base.Fill(w, st) }) } func (w *Mget) Process() { w.processEnable = true defer func() { w.processEnable = false }() fmt.Println() p := mpb.New() var filler mpb.BarFiller filler = w.processMiddleware(filler) bar := p.New(int64(w.ContentLength), mpb.BarStyle().Rbound("|"), mpb.BarExtender(filler, true), // all bars share same extender filler mpb.PrependDecorators( decor.Counters(decor.SizeB1024(0), "% .2f / % .2f"), ), mpb.AppendDecorators( decor.AverageETA(decor.ET_STYLE_GO), decor.Name(" ] "), decor.AverageSpeed(decor.SizeB1024(0), "% .2f "), ), ) defer p.Wait() lastTime := time.Now() bar.SetRefill(int64(w.Redo.Total())) bar.DecoratorAverageAdjust(time.Now().Add(time.Millisecond * time.Duration(-w.TimeCost))) for { select { case <-w.ctx.Done(): bar.SetCurrent(int64(w.Redo.Total())) if w.dynLength { bar.SetTotal(int64(w.Redo.ContentLength), true) } bar.Abort(false) return case <-time.After(time.Second): if !w.writeEnable { bar.SetCurrent(int64(w.Redo.Total())) if w.dynLength { bar.SetTotal(int64(w.Redo.ContentLength), true) } bar.Abort(true) return } now := w.Redo.Total() date := time.Now() bar.EwmaSetCurrent(int64(now), date.Sub(lastTime)) lastTime = date if w.dynLength { bar.SetTotal(int64(w.Redo.ContentLength), false) } } } }