Merge pull request #23648 from containers/renovate/github.com-vbauerster-mpb-v8-8.x

fix(deps): update module github.com/vbauerster/mpb/v8 to v8.8.1
This commit is contained in:
openshift-merge-bot[bot]
2024-08-16 16:31:24 +00:00
committed by GitHub
14 changed files with 192 additions and 222 deletions

2
go.mod
View File

@ -67,7 +67,7 @@ require (
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/vbauerster/mpb/v8 v8.7.5
github.com/vbauerster/mpb/v8 v8.8.1
github.com/vishvananda/netlink v1.2.1-beta.2
go.etcd.io/bbolt v1.3.10
golang.org/x/crypto v0.26.0

4
go.sum
View File

@ -510,8 +510,8 @@ github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
github.com/vbauerster/mpb/v8 v8.7.5 h1:hUF3zaNsuaBBwzEFoCvfuX3cpesQXZC0Phm/JcHZQ+c=
github.com/vbauerster/mpb/v8 v8.7.5/go.mod h1:bRCnR7K+mj5WXKsy0NWB6Or+wctYGvVwKn6huwvxKa0=
github.com/vbauerster/mpb/v8 v8.8.1 h1:7MtGwKWa9RhThnmUDb7d4Ze6YVw2lCwA60ENsNUxX6k=
github.com/vbauerster/mpb/v8 v8.8.1/go.mod h1:JfCCrtcMsJwP6ZwMn9e5LMnNyp3TVNpUWWkN+nd4EWk=
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=

View File

@ -19,14 +19,15 @@ type Bar struct {
priority int // used by heap
frameCh chan *renderFrame
operateState chan func(*bState)
done chan struct{}
container *Progress
bs *bState
bsOk chan struct{}
ctx context.Context
cancel func()
}
type syncTable [2][]chan int
type extenderFunc func([]io.Reader, decor.Statistics) ([]io.Reader, error)
type extenderFunc func(decor.Statistics, ...io.Reader) ([]io.Reader, error)
// bState is actual bar's state.
type bState struct {
@ -38,7 +39,6 @@ type bState struct {
current int64
refill int64
trimSpace bool
completed bool
aborted bool
triggerComplete bool
rmOnComplete bool
@ -70,13 +70,14 @@ func newBar(ctx context.Context, container *Progress, bs *bState) *Bar {
priority: bs.priority,
frameCh: make(chan *renderFrame, 1),
operateState: make(chan func(*bState)),
done: make(chan struct{}),
bsOk: make(chan struct{}),
container: container,
ctx: ctx,
cancel: cancel,
}
container.bwg.Add(1)
go bar.serve(ctx, bs)
go bar.serve(bs)
return bar
}
@ -89,11 +90,13 @@ func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser {
if r == nil {
panic("expected non nil io.Reader")
}
result := make(chan bool)
result := make(chan io.ReadCloser)
select {
case b.operateState <- func(s *bState) { result <- len(s.ewmaDecorators) != 0 }:
return newProxyReader(r, b, <-result)
case <-b.done:
case b.operateState <- func(s *bState) {
result <- newProxyReader(r, b, len(s.ewmaDecorators) != 0)
}:
return <-result
case <-b.ctx.Done():
return nil
}
}
@ -105,11 +108,13 @@ func (b *Bar) ProxyWriter(w io.Writer) io.WriteCloser {
if w == nil {
panic("expected non nil io.Writer")
}
result := make(chan bool)
result := make(chan io.WriteCloser)
select {
case b.operateState <- func(s *bState) { result <- len(s.ewmaDecorators) != 0 }:
return newProxyWriter(w, b, <-result)
case <-b.done:
case b.operateState <- func(s *bState) {
result <- newProxyWriter(w, b, len(s.ewmaDecorators) != 0)
}:
return <-result
case <-b.ctx.Done():
return nil
}
}
@ -120,7 +125,7 @@ func (b *Bar) ID() int {
select {
case b.operateState <- func(s *bState) { result <- s.id }:
return <-result
case <-b.done:
case <-b.bsOk:
return b.bs.id
}
}
@ -131,7 +136,7 @@ func (b *Bar) Current() int64 {
select {
case b.operateState <- func(s *bState) { result <- s.current }:
return <-result
case <-b.done:
case <-b.bsOk:
return b.bs.current
}
}
@ -149,7 +154,7 @@ func (b *Bar) SetRefill(amount int64) {
s.refill = s.current
}
}:
case <-b.done:
case <-b.ctx.Done():
}
}
@ -168,7 +173,7 @@ func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
for d := range iter {
cb(unwrap(d))
}
case <-b.done:
case <-b.ctx.Done():
}
}
@ -183,13 +188,12 @@ func (b *Bar) EnableTriggerComplete() {
}
if s.current >= s.total {
s.current = s.total
s.completed = true
b.triggerCompletion(s)
s.triggerCompletion(b)
} else {
s.triggerComplete = true
}
}:
case <-b.done:
case <-b.ctx.Done():
}
}
@ -211,11 +215,10 @@ func (b *Bar) SetTotal(total int64, complete bool) {
}
if complete {
s.current = s.total
s.completed = true
b.triggerCompletion(s)
s.triggerCompletion(b)
}
}:
case <-b.done:
case <-b.ctx.Done():
}
}
@ -229,11 +232,10 @@ func (b *Bar) SetCurrent(current int64) {
s.current = current
if s.triggerComplete && s.current >= s.total {
s.current = s.total
s.completed = true
b.triggerCompletion(s)
s.triggerCompletion(b)
}
}:
case <-b.done:
case <-b.ctx.Done():
}
}
@ -243,17 +245,22 @@ func (b *Bar) EwmaSetCurrent(current int64, iterDur time.Duration) {
if current < 0 {
return
}
result := make(chan *sync.WaitGroup)
select {
case b.operateState <- func(s *bState) {
s.decoratorEwmaUpdate(current-s.current, iterDur)
n := current - s.current
s.current = current
if s.triggerComplete && s.current >= s.total {
s.current = s.total
s.completed = true
b.triggerCompletion(s)
s.triggerCompletion(b)
}
var wg sync.WaitGroup
s.decoratorEwmaUpdate(n, iterDur, &wg)
result <- &wg
}:
case <-b.done:
wg := <-result
wg.Wait()
case <-b.ctx.Done():
}
}
@ -269,19 +276,15 @@ func (b *Bar) IncrBy(n int) {
// IncrInt64 increments progress by amount of n.
func (b *Bar) IncrInt64(n int64) {
if n <= 0 {
return
}
select {
case b.operateState <- func(s *bState) {
s.current += n
if s.triggerComplete && s.current >= s.total {
s.current = s.total
s.completed = true
b.triggerCompletion(s)
s.triggerCompletion(b)
}
}:
case <-b.done:
case <-b.ctx.Done():
}
}
@ -298,17 +301,21 @@ func (b *Bar) EwmaIncrBy(n int, iterDur time.Duration) {
// EwmaIncrInt64 increments progress by amount of n and updates EWMA based
// decorators by dur of a single iteration.
func (b *Bar) EwmaIncrInt64(n int64, iterDur time.Duration) {
result := make(chan *sync.WaitGroup)
select {
case b.operateState <- func(s *bState) {
s.decoratorEwmaUpdate(n, iterDur)
s.current += n
if s.triggerComplete && s.current >= s.total {
s.current = s.total
s.completed = true
b.triggerCompletion(s)
s.triggerCompletion(b)
}
var wg sync.WaitGroup
s.decoratorEwmaUpdate(n, iterDur, &wg)
result <- &wg
}:
case <-b.done:
wg := <-result
wg.Wait()
case <-b.ctx.Done():
}
}
@ -317,8 +324,12 @@ func (b *Bar) EwmaIncrInt64(n int64, iterDur time.Duration) {
// or after progress resume.
func (b *Bar) DecoratorAverageAdjust(start time.Time) {
select {
case b.operateState <- func(s *bState) { s.decoratorAverageAdjust(start) }:
case <-b.done:
case b.operateState <- func(s *bState) {
for _, d := range s.averageDecorators {
d.AverageAdjust(start)
}
}:
case <-b.ctx.Done():
}
}
@ -336,14 +347,14 @@ func (b *Bar) SetPriority(priority int) {
func (b *Bar) Abort(drop bool) {
select {
case b.operateState <- func(s *bState) {
if s.completed || s.aborted {
if s.aborted || s.completed() {
return
}
s.aborted = true
s.rmOnComplete = drop
b.triggerCompletion(s)
s.triggerCompletion(b)
}:
case <-b.done:
case <-b.ctx.Done():
}
}
@ -353,7 +364,7 @@ func (b *Bar) Aborted() bool {
select {
case b.operateState <- func(s *bState) { result <- s.aborted }:
return <-result
case <-b.done:
case <-b.bsOk:
return b.bs.aborted
}
}
@ -362,41 +373,42 @@ func (b *Bar) Aborted() bool {
func (b *Bar) Completed() bool {
result := make(chan bool)
select {
case b.operateState <- func(s *bState) { result <- s.completed }:
case b.operateState <- func(s *bState) { result <- s.completed() }:
return <-result
case <-b.done:
return b.bs.completed
case <-b.bsOk:
return b.bs.completed()
}
}
// IsRunning reports whether the bar is running, i.e. not yet completed
// and not yet aborted.
// IsRunning reports whether the bar is in running state.
func (b *Bar) IsRunning() bool {
result := make(chan bool)
select {
case b.operateState <- func(s *bState) { result <- !s.completed && !s.aborted }:
return <-result
case <-b.done:
case <-b.ctx.Done():
return false
default:
return true
}
}
// Wait blocks until bar is completed or aborted.
func (b *Bar) Wait() {
<-b.done
<-b.bsOk
}
func (b *Bar) serve(ctx context.Context, bs *bState) {
defer b.container.bwg.Done()
func (b *Bar) serve(bs *bState) {
for {
select {
case op := <-b.operateState:
op(bs)
case <-ctx.Done():
bs.aborted = !bs.completed
bs.decoratorShutdownNotify()
case <-b.ctx.Done():
shutdownListeners := bs.shutdownListeners
bs.aborted = !bs.completed()
b.bs = bs
close(b.done)
close(b.bsOk)
for _, d := range shutdownListeners {
d.OnShutdown()
}
b.container.bwg.Done()
return
}
}
@ -405,7 +417,7 @@ func (b *Bar) serve(ctx context.Context, bs *bState) {
func (b *Bar) render(tw int) {
fn := func(s *bState) {
frame := new(renderFrame)
stat := newStatistics(tw, s)
stat := s.newStatistics(tw)
r, err := s.draw(stat)
if err != nil {
for _, buf := range s.buffers {
@ -415,11 +427,8 @@ func (b *Bar) render(tw int) {
b.frameCh <- frame
return
}
frame.rows = append(frame.rows, r)
if s.extender != nil {
frame.rows, frame.err = s.extender(frame.rows, stat)
}
if s.completed || s.aborted {
frame.rows, frame.err = s.extender(stat, r)
if s.aborted || s.completed() {
frame.shutdown = s.shutdown
frame.rmOnComplete = s.rmOnComplete
frame.noPop = s.noPop
@ -430,22 +439,11 @@ func (b *Bar) render(tw int) {
}
select {
case b.operateState <- fn:
case <-b.done:
case <-b.bsOk:
fn(b.bs)
}
}
func (b *Bar) triggerCompletion(s *bState) {
if s.autoRefresh {
// Technically this call isn't required, but if refresh rate is set to
// one hour for example and bar completes within a few minutes p.Wait()
// will wait for one hour. This call helps to avoid unnecessary waiting.
go b.tryEarlyRefresh(s.renderReq)
} else {
b.cancel()
}
}
func (b *Bar) tryEarlyRefresh(renderReq chan<- time.Time) {
var otherRunning int
b.container.traverseBars(func(bar *Bar) bool {
@ -459,7 +457,7 @@ func (b *Bar) tryEarlyRefresh(renderReq chan<- time.Time) {
for {
select {
case renderReq <- time.Now():
case <-b.done:
case <-b.ctx.Done():
return
}
}
@ -471,7 +469,7 @@ func (b *Bar) wSyncTable() syncTable {
select {
case b.operateState <- func(s *bState) { result <- s.wSyncTable() }:
return <-result
case <-b.done:
case <-b.bsOk:
return b.bs.wSyncTable()
}
}
@ -551,58 +549,49 @@ func (s *bState) wSyncTable() (table syncTable) {
return table
}
func (s bState) decoratorEwmaUpdate(n int64, dur time.Duration) {
var wg sync.WaitGroup
for i := 0; i < len(s.ewmaDecorators); i++ {
switch d := s.ewmaDecorators[i]; i {
case len(s.ewmaDecorators) - 1:
func (s *bState) sortDecorators(decorators []decor.Decorator) {
for _, d := range decorators {
d := unwrap(d)
if d, ok := d.(decor.AverageDecorator); ok {
s.averageDecorators = append(s.averageDecorators, d)
}
if d, ok := d.(decor.EwmaDecorator); ok {
s.ewmaDecorators = append(s.ewmaDecorators, d)
}
if d, ok := d.(decor.ShutdownListener); ok {
s.shutdownListeners = append(s.shutdownListeners, d)
}
}
}
func (s *bState) triggerCompletion(b *Bar) {
s.triggerComplete = true
if s.autoRefresh {
// Technically this call isn't required, but if refresh rate is set to
// one hour for example and bar completes within a few minutes p.Wait()
// will wait for one hour. This call helps to avoid unnecessary waiting.
go b.tryEarlyRefresh(s.renderReq)
} else {
b.cancel()
}
}
func (s bState) completed() bool {
return s.triggerComplete && s.current == s.total
}
func (s bState) decoratorEwmaUpdate(n int64, dur time.Duration, wg *sync.WaitGroup) {
wg.Add(len(s.ewmaDecorators))
for _, d := range s.ewmaDecorators {
d := d
go func() {
d.EwmaUpdate(n, dur)
default:
wg.Add(1)
go func() {
d.EwmaUpdate(n, dur)
wg.Done()
}()
}
wg.Done()
}()
}
wg.Wait()
}
func (s bState) decoratorAverageAdjust(start time.Time) {
var wg sync.WaitGroup
for i := 0; i < len(s.averageDecorators); i++ {
switch d := s.averageDecorators[i]; i {
case len(s.averageDecorators) - 1:
d.AverageAdjust(start)
default:
wg.Add(1)
go func() {
d.AverageAdjust(start)
wg.Done()
}()
}
}
wg.Wait()
}
func (s bState) decoratorShutdownNotify() {
var wg sync.WaitGroup
for i := 0; i < len(s.shutdownListeners); i++ {
switch d := s.shutdownListeners[i]; i {
case len(s.shutdownListeners) - 1:
d.OnShutdown()
default:
wg.Add(1)
go func() {
d.OnShutdown()
wg.Done()
}()
}
}
wg.Wait()
}
func newStatistics(tw int, s *bState) decor.Statistics {
func (s bState) newStatistics(tw int) decor.Statistics {
return decor.Statistics{
AvailableWidth: tw,
RequestedWidth: s.reqWidth,
@ -610,7 +599,7 @@ func newStatistics(tw int, s *bState) decor.Statistics {
Total: s.total,
Current: s.current,
Refill: s.refill,
Completed: s.completed,
Completed: s.completed(),
Aborted: s.aborted,
}
}

View File

@ -233,7 +233,7 @@ func (s *bFiller) Fill(w io.Writer, stat decor.Statistics) error {
var tip component
var refilling, filling, padding []byte
var fillCount int
curWidth := int(internal.PercentageRound(stat.Total, stat.Current, int64(width)))
curWidth := int(internal.PercentageRound(stat.Total, stat.Current, uint(width)))
if curWidth != 0 {
if !stat.Completed || s.tipOnComplete {
@ -243,7 +243,7 @@ func (s *bFiller) Fill(w io.Writer, stat decor.Statistics) error {
}
switch refWidth := 0; {
case stat.Refill != 0:
refWidth = int(internal.PercentageRound(stat.Total, stat.Refill, int64(width)))
refWidth = int(internal.PercentageRound(stat.Total, stat.Refill, uint(width)))
curWidth -= refWidth
refWidth += curWidth
fallthrough

View File

@ -24,6 +24,7 @@ func inspect(decorators []decor.Decorator) (dest []decor.Decorator) {
func PrependDecorators(decorators ...decor.Decorator) BarOption {
decorators = inspect(decorators)
return func(s *bState) {
s.sortDecorators(decorators)
s.decorators[0] = decorators
}
}
@ -32,6 +33,7 @@ func PrependDecorators(decorators ...decor.Decorator) BarOption {
func AppendDecorators(decorators ...decor.Decorator) BarOption {
decorators = inspect(decorators)
return func(s *bState) {
s.sortDecorators(decorators)
s.decorators[1] = decorators
}
}
@ -112,6 +114,9 @@ func BarExtender(filler BarFiller, rev bool) BarOption {
if filler == nil {
return nil
}
if f, ok := filler.(BarFillerFunc); ok && f == nil {
return nil
}
fn := makeExtenderFunc(filler, rev)
return func(s *bState) {
s.extender = fn
@ -120,28 +125,27 @@ func BarExtender(filler BarFiller, rev bool) BarOption {
func makeExtenderFunc(filler BarFiller, rev bool) extenderFunc {
buf := new(bytes.Buffer)
base := func(rows []io.Reader, stat decor.Statistics) ([]io.Reader, error) {
base := func(stat decor.Statistics, rows ...io.Reader) ([]io.Reader, error) {
err := filler.Fill(buf, stat)
if err != nil {
buf.Reset()
return rows, err
}
for {
b, err := buf.ReadBytes('\n')
line, err := buf.ReadBytes('\n')
if err != nil {
buf.Reset()
break
}
rows = append(rows, bytes.NewReader(b))
rows = append(rows, bytes.NewReader(line))
}
return rows, err
}
if !rev {
return base
}
return func(rows []io.Reader, stat decor.Statistics) ([]io.Reader, error) {
rows, err := base(rows, stat)
return func(stat decor.Statistics, rows ...io.Reader) ([]io.Reader, error) {
rows, err := base(stat, rows...)
if err != nil {
return rows, err
}

View File

@ -17,15 +17,15 @@ func Elapsed(style TimeStyle, wcc ...WC) Decorator {
//
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
//
// `startTime` start time
// `start` start time
//
// `wcc` optional WC config
func NewElapsed(style TimeStyle, startTime time.Time, wcc ...WC) Decorator {
func NewElapsed(style TimeStyle, start time.Time, wcc ...WC) Decorator {
var msg string
producer := chooseTimeProducer(style)
fn := func(s Statistics) string {
if !s.Completed {
msg = producer(time.Since(startTime))
if !s.Completed && !s.Aborted {
msg = producer(time.Since(start))
}
return msg
}

View File

@ -33,13 +33,18 @@ func (f TimeNormalizerFunc) Normalize(src time.Duration) time.Duration {
// decorator to work correctly you have to measure each iteration's duration
// and pass it to one of the (*Bar).EwmaIncr... family methods.
func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
return EwmaNormalizedETA(style, age, nil, wcc...)
}
// EwmaNormalizedETA same as EwmaETA but with TimeNormalizer option.
func EwmaNormalizedETA(style TimeStyle, age float64, normalizer TimeNormalizer, wcc ...WC) Decorator {
var average ewma.MovingAverage
if age == 0 {
average = ewma.NewMovingAverage()
} else {
average = ewma.NewMovingAverage(age)
}
return MovingAverageETA(style, average, nil, wcc...)
return MovingAverageETA(style, NewThreadSafeMovingAverage(average), normalizer, wcc...)
}
// MovingAverageETA decorator relies on MovingAverage implementation to calculate its average.
@ -52,6 +57,9 @@ func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
//
// `wcc` optional WC config
func MovingAverageETA(style TimeStyle, average ewma.MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator {
if average == nil {
average = NewMedian()
}
d := &movingAverageETA{
WC: initWC(wcc...),
producer: chooseTimeProducer(style),
@ -78,6 +86,7 @@ func (d *movingAverageETA) Decor(s Statistics) (string, int) {
return d.Format(d.producer(remaining))
}
// EwmaUpdate is called concurrently with (d *movingAverageETA).Decor
func (d *movingAverageETA) EwmaUpdate(n int64, dur time.Duration) {
if n <= 0 {
d.zDur += dur
@ -105,15 +114,15 @@ func AverageETA(style TimeStyle, wcc ...WC) Decorator {
//
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
//
// `startTime` start time
// `start` start time
//
// `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
//
// `wcc` optional WC config
func NewAverageETA(style TimeStyle, startTime time.Time, normalizer TimeNormalizer, wcc ...WC) Decorator {
func NewAverageETA(style TimeStyle, start time.Time, normalizer TimeNormalizer, wcc ...WC) Decorator {
d := &averageETA{
WC: initWC(wcc...),
startTime: startTime,
start: start,
normalizer: normalizer,
producer: chooseTimeProducer(style),
}
@ -122,7 +131,7 @@ func NewAverageETA(style TimeStyle, startTime time.Time, normalizer TimeNormaliz
type averageETA struct {
WC
startTime time.Time
start time.Time
normalizer TimeNormalizer
producer func(time.Duration) string
}
@ -130,7 +139,7 @@ type averageETA struct {
func (d *averageETA) Decor(s Statistics) (string, int) {
var remaining time.Duration
if s.Current != 0 {
durPerItem := float64(time.Since(d.startTime)) / float64(s.Current)
durPerItem := float64(time.Since(d.start)) / float64(s.Current)
durPerItem = math.Round(durPerItem)
remaining = time.Duration((s.Total - s.Current) * int64(durPerItem))
if d.normalizer != nil {
@ -140,8 +149,8 @@ func (d *averageETA) Decor(s Statistics) (string, int) {
return d.Format(d.producer(remaining))
}
func (d *averageETA) AverageAdjust(startTime time.Time) {
d.startTime = startTime
func (d *averageETA) AverageAdjust(start time.Time) {
d.start = start
}
// MaxTolerateTimeNormalizer returns implementation of TimeNormalizer.

View File

@ -70,5 +70,5 @@ func (s *medianWindow) Set(value float64) {
// NewMedian is fixed last 3 samples median MovingAverage.
func NewMedian() ewma.MovingAverage {
return new(medianWindow)
return NewThreadSafeMovingAverage(new(medianWindow))
}

View File

@ -61,7 +61,7 @@ func NewPercentage(format string, wcc ...WC) Decorator {
format = "% d"
}
f := func(s Statistics) string {
p := internal.PercentageRound(s.Total, s.Current, 100)
p := internal.Percentage(uint(s.Total), uint(s.Current), 100)
return fmt.Sprintf(format, percentageType(p))
}
return Any(f, wcc...)

View File

@ -21,15 +21,15 @@ var (
//
// fmt.Printf("%.1f", FmtAsSpeed(SizeB1024(2048)))
func FmtAsSpeed(input fmt.Formatter) fmt.Formatter {
return speedFormatter{input}
return &speedFormatter{input}
}
type speedFormatter struct {
fmt.Formatter
}
func (self speedFormatter) Format(st fmt.State, verb rune) {
self.Formatter.Format(st, verb)
func (s *speedFormatter) Format(st fmt.State, verb rune) {
s.Formatter.Format(st, verb)
_, err := io.WriteString(st, "/s")
if err != nil {
panic(err)
@ -46,7 +46,7 @@ func EwmaSpeed(unit interface{}, format string, age float64, wcc ...WC) Decorato
} else {
average = ewma.NewMovingAverage(age)
}
return MovingAverageSpeed(unit, format, average, wcc...)
return MovingAverageSpeed(unit, format, NewThreadSafeMovingAverage(average), wcc...)
}
// MovingAverageSpeed decorator relies on MovingAverage implementation
@ -93,6 +93,7 @@ func (d *movingAverageSpeed) Decor(_ Statistics) (string, int) {
return d.Format(str)
}
// EwmaUpdate is called concurrently with (d *movingAverageSpeed).Decor
func (d *movingAverageSpeed) EwmaUpdate(n int64, dur time.Duration) {
if n <= 0 {
d.zDur += dur
@ -120,7 +121,7 @@ func AverageSpeed(unit interface{}, format string, wcc ...WC) Decorator {
//
// `format` printf compatible verb for value, like "%f" or "%d"
//
// `startTime` start time
// `start` start time
//
// `wcc` optional WC config
//
@ -130,32 +131,32 @@ func AverageSpeed(unit interface{}, format string, wcc ...WC) Decorator {
// unit=SizeB1024(0), format="% .1f" output: "1.0 MiB/s"
// unit=SizeB1000(0), format="%.1f" output: "1.0MB/s"
// unit=SizeB1000(0), format="% .1f" output: "1.0 MB/s"
func NewAverageSpeed(unit interface{}, format string, startTime time.Time, wcc ...WC) Decorator {
func NewAverageSpeed(unit interface{}, format string, start time.Time, wcc ...WC) Decorator {
d := &averageSpeed{
WC: initWC(wcc...),
startTime: startTime,
producer: chooseSpeedProducer(unit, format),
WC: initWC(wcc...),
start: start,
producer: chooseSpeedProducer(unit, format),
}
return d
}
type averageSpeed struct {
WC
startTime time.Time
producer func(float64) string
msg string
start time.Time
producer func(float64) string
msg string
}
func (d *averageSpeed) Decor(s Statistics) (string, int) {
if !s.Completed {
speed := float64(s.Current) / float64(time.Since(d.startTime))
speed := float64(s.Current) / float64(time.Since(d.start))
d.msg = d.producer(speed * 1e9)
}
return d.Format(d.msg)
}
func (d *averageSpeed) AverageAdjust(startTime time.Time) {
d.startTime = startTime
func (d *averageSpeed) AverageAdjust(start time.Time) {
d.start = start
}
func chooseSpeedProducer(unit interface{}, format string) func(float64) string {

View File

@ -14,9 +14,9 @@ func Percentage(total, current, width uint) float64 {
}
// PercentageRound same as Percentage but with math.Round.
func PercentageRound(total, current, width int64) float64 {
if total < 0 || current < 0 || width < 0 {
func PercentageRound(total, current int64, width uint) float64 {
if total < 0 || current < 0 {
return 0
}
return math.Round(Percentage(uint(total), uint(current), uint(width)))
return math.Round(Percentage(uint(total), uint(current), width))
}

View File

@ -126,6 +126,9 @@ func (p *Progress) AddSpinner(total int64, options ...BarOption) *Bar {
// New creates a bar by calling `Build` method on provided `BarFillerBuilder`.
func (p *Progress) New(total int64, builder BarFillerBuilder, options ...BarOption) *Bar {
if builder == nil {
return p.MustAdd(total, nil, options...)
}
return p.MustAdd(total, builder.Build(), options...)
}
@ -147,12 +150,10 @@ func (p *Progress) MustAdd(total int64, filler BarFiller, options ...BarOption)
func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) (*Bar, error) {
if filler == nil {
filler = NopStyle().Build()
} else if f, ok := filler.(BarFillerFunc); ok && f == nil {
filler = NopStyle().Build()
}
type result struct {
bar *Bar
bs *bState
}
ch := make(chan result)
ch := make(chan *Bar)
select {
case p.operateState <- func(ps *pState) {
bs := ps.makeBarState(total, filler, options...)
@ -163,22 +164,9 @@ func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) (*Ba
ps.hm.push(bar, true)
}
ps.idCount++
ch <- result{bar, bs}
ch <- bar
}:
res := <-ch
bar, bs := res.bar, res.bs
bar.TraverseDecorators(func(d decor.Decorator) {
if d, ok := d.(decor.AverageDecorator); ok {
bs.averageDecorators = append(bs.averageDecorators, d)
}
if d, ok := d.(decor.EwmaDecorator); ok {
bs.ewmaDecorators = append(bs.ewmaDecorators, d)
}
if d, ok := d.(decor.ShutdownListener); ok {
bs.shutdownListeners = append(bs.shutdownListeners, d)
}
})
return bar, nil
return <-ch, nil
case <-p.done:
return nil, DoneError
}
@ -237,13 +225,12 @@ func (p *Progress) Write(b []byte) (int, error) {
// Wait waits for all bars to complete and finally shutdowns container. After
// this method has been called, there is no way to reuse `*Progress` instance.
func (p *Progress) Wait() {
p.bwg.Wait()
p.Shutdown()
// wait for user wg, if any
if p.uwg != nil {
p.uwg.Wait()
}
p.bwg.Wait()
p.Shutdown()
}
// Shutdown cancels any running bar immediately and then shutdowns `*Progress`
@ -453,6 +440,9 @@ func (s pState) makeBarState(total int64, filler BarFiller, options ...BarOption
filler: filler,
renderReq: s.renderReq,
autoRefresh: s.autoRefresh,
extender: func(_ decor.Statistics, rows ...io.Reader) ([]io.Reader, error) {
return rows, nil
},
}
if total > 0 {

View File

@ -69,28 +69,5 @@ func toReadCloser(r io.Reader) io.ReadCloser {
if rc, ok := r.(io.ReadCloser); ok {
return rc
}
return toNopReadCloser(r)
}
func toNopReadCloser(r io.Reader) io.ReadCloser {
if _, ok := r.(io.WriterTo); ok {
return nopReadCloserWriterTo{r}
}
return nopReadCloser{r}
}
type nopReadCloser struct {
io.Reader
}
func (nopReadCloser) Close() error { return nil }
type nopReadCloserWriterTo struct {
io.Reader
}
func (nopReadCloserWriterTo) Close() error { return nil }
func (c nopReadCloserWriterTo) WriteTo(w io.Writer) (int64, error) {
return c.Reader.(io.WriterTo).WriteTo(w)
return io.NopCloser(r)
}

2
vendor/modules.txt vendored
View File

@ -1082,7 +1082,7 @@ github.com/ulikunitz/xz/lzma
github.com/vbatts/tar-split/archive/tar
github.com/vbatts/tar-split/tar/asm
github.com/vbatts/tar-split/tar/storage
# github.com/vbauerster/mpb/v8 v8.7.5
# github.com/vbauerster/mpb/v8 v8.8.1
## explicit; go 1.17
github.com/vbauerster/mpb/v8
github.com/vbauerster/mpb/v8/cwriter