vbauerster / mpb

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

Bug: Bars are not completely removed #122

Closed nilsbeck closed 1 year ago

nilsbeck commented 1 year ago

Hey there, I noticed that bars are only removed until there is one bar left. The last bar will not be removed. You can see that by making a minimal change in the example you put together here: https://github.com/vbauerster/mpb/tree/master/_examples/remove

change: mpb.BarOptional(mpb.BarRemoveOnComplete(), i == 0), for: mpb.BarOptional(mpb.BarRemoveOnComplete(), true),

Seen behavior: 2 of 3 bars are removed. Expected behavior: all bars are removed.

nilsbeck commented 1 year ago

To be able to copy paste:

`package main

import ( "fmt" "math/rand" "sync" "time"

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

)

func main() { var wg sync.WaitGroup // passed wg will be accounted at p.Wait() call p := mpb.New(mpb.WithWaitGroup(&wg)) total := 100 numBars := 3 wg.Add(numBars)

for i := 0; i < numBars; i++ {
    name := fmt.Sprintf("Bar#%d:", i)
    bar := p.AddBar(int64(total),
        mpb.BarID(i),
        mpb.BarOptional(mpb.BarRemoveOnComplete(), true),
        mpb.PrependDecorators(
            decor.Name(name),
        ),
        mpb.AppendDecorators(
            decor.Any(func(s decor.Statistics) string {
                return fmt.Sprintf("completed: %v", s.Completed)
            }, decor.WCSyncSpaceR),
            decor.Any(func(s decor.Statistics) string {
                return fmt.Sprintf("aborted: %v", s.Aborted)
            }, decor.WCSyncSpaceR),
            decor.OnComplete(decor.NewPercentage("%d", decor.WCSyncSpace), "done"),
            decor.OnAbort(decor.NewPercentage("%d", decor.WCSyncSpace), "ohno"),
        ),
    )
    go func() {
        defer wg.Done()
        rng := rand.New(rand.NewSource(time.Now().UnixNano()))
        max := 100 * time.Millisecond
        for i := 0; bar.IsRunning(); i++ {
            if bar.ID() == 2 && i >= 42 {
                go bar.Abort(false)
            }
            time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10)
            bar.Increment()
        }
    }()
}
// wait for passed wg and for all bars to complete and flush
p.Wait()

}`

vbauerster commented 1 year ago

I was able to reproduce with change you mentioned and disabled bar.Abort case:

https://github.com/vbauerster/mpb/blob/314158faaf7557a31a22ab69bd491799d46f2e3f/_examples/remove/main.go#L46

Fix commit added to the master branch. Can you please confirm it works for you?

nilsbeck commented 1 year ago

Hey, yes. That fixes it! I also tested it my own example (my code base) which is slightly more complex than the example. and it is working there as well!

Thank you for being so responsive and fixing this!