Codebase list golang-github-vbauerster-mpb / ebe97c0
New option mpb.WithWaitGroup Vladimir Bauer 8 years ago
13 changed file(s) with 60 addition(s) and 46 deletion(s). Raw diff Collapse all Expand all
7676 own goroutine, therefore adding multiple bars is easy and safe:
7777
7878 ```go
79 p := mpb.New()
79 var wg sync.WaitGroup
80 p := mpb.New(mpb.WithWaitGroup(&wg))
8081 total := 100
8182 numBars := 3
82 var wg sync.WaitGroup
8383 wg.Add(numBars)
8484
8585 for i := 0; i < numBars; i++ {
9696 go func() {
9797 defer wg.Done()
9898 for i := 0; i < total; i++ {
99 time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
100 bar.Incr(1)
99 time.Sleep(time.Duration(rand.Intn(10)+1) * time.Second / 100)
100 bar.Increment()
101101 }
102102 }()
103103 }
104 wg.Wait() // Wait for goroutines to finish
105 p.Stop() // Stop mpb's rendering goroutine
104 // Wait for incr loop goroutines to finish,
105 // and shutdown mpb's rendering goroutine
106 p.Stop()
106107 ```
107108
108109 ![simple.gif](examples/gifs/simple.gif)
3838 )
3939
4040 for i := 0; i < total; i++ {
41 time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
42 bar.Incr(1) // increment progress bar
41 time.Sleep(time.Duration(rand.Intn(10)+1) * time.Second / 100)
42 bar.Increment()
4343 }
4444
4545 p.Stop()
5050 bar := p.AddBar(100, mpb.AppendDecorators(decor.Percentage(5, 0)))
5151
5252 for bar.InProgress() {
53 time.Sleep(time.Millisecond * 20)
54 bar.Incr(1)
53 time.Sleep(time.Duration(rand.Intn(10)+1) * time.Second / 100)
54 bar.Increment()
5555 }
5656 }
2121 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
2222 defer cancel()
2323
24 p := mpb.New(mpb.WithContext(ctx))
25
2624 var wg sync.WaitGroup
25 p := mpb.New(
26 mpb.WithWaitGroup(&wg),
27 mpb.WithContext(ctx),
28 )
2729 total := 100
2830 numBars := 3
2931 wg.Add(numBars)
5557 }()
5658 }
5759
58 wg.Wait()
5960 p.Stop()
6061 fmt.Println("stop")
6162 }
1919 url2 := "https://homebrew.bintray.com/bottles/libtiff-4.0.7.sierra.bottle.tar.gz"
2020
2121 var wg sync.WaitGroup
22 p := mpb.New(mpb.WithWidth(64))
22 p := mpb.New(mpb.WithWaitGroup(&wg))
2323
2424 for i, url := range [...]string{url1, url2} {
2525 wg.Add(1)
2727 go download(&wg, p, name, url)
2828 }
2929
30 wg.Wait()
3130 p.Stop()
3231 fmt.Println("Finished")
3332 }
1515
1616 func main() {
1717
18 p := mpb.New(mpb.WithWidth(64))
19
18 var wg sync.WaitGroup
19 p := mpb.New(mpb.WithWaitGroup(&wg))
2020 total := 100
2121 numBars := 3
22 var wg sync.WaitGroup
2322 wg.Add(numBars)
2423
2524 for i := 0; i < numBars; i++ {
4746 }()
4847 }
4948
50 wg.Wait()
5149 p.Stop()
5250 fmt.Println("stop")
5351 }
1515
1616 func main() {
1717
18 p := mpb.New(mpb.WithWidth(64))
19
18 var wg sync.WaitGroup
19 p := mpb.New(mpb.WithWaitGroup(&wg))
2020 total := 100
2121 numBars := 3
22 var wg sync.WaitGroup
2322 wg.Add(numBars)
2423
2524 for i := 0; i < numBars; i++ {
4746 }()
4847 }
4948
50 wg.Wait()
5149 p.Stop()
5250 fmt.Println("stop")
5351 }
1515
1616 func main() {
1717
18 p := mpb.New(mpb.WithWidth(64))
19
18 var wg sync.WaitGroup
19 p := mpb.New(mpb.WithWaitGroup(&wg))
2020 total := 100
2121 numBars := 3
22 var wg sync.WaitGroup
2322 wg.Add(numBars)
2423
2524 for i := 0; i < numBars; i++ {
5150 }()
5251 }
5352
54 wg.Wait()
5553 p.Stop()
5654 fmt.Println("stop")
5755 }
1010 )
1111
1212 func main() {
13 p := mpb.New()
13 var wg sync.WaitGroup
14 p := mpb.New(mpb.WithWaitGroup(&wg))
1415 total := 100
1516 numBars := 3
16 var wg sync.WaitGroup
1717 wg.Add(numBars)
1818
1919 for i := 0; i < numBars; i++ {
3030 go func() {
3131 defer wg.Done()
3232 for i := 0; i < total; i++ {
33 time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
34 bar.Incr(1)
33 time.Sleep(time.Duration(rand.Intn(10)+1) * time.Second / 100)
34 bar.Increment()
3535 }
3636 }()
3737 }
38 wg.Wait() // Wait for goroutines to finish
39 p.Stop() // Stop mpb's rendering goroutine
38 // Wait for incr loop goroutines to finish,
39 // and shutdown mpb's rendering goroutine
40 p.Stop()
4041 }
3838 )
3939
4040 for i := 0; i < total; i++ {
41 time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
42 bar.Incr(1) // increment progress bar
41 time.Sleep(time.Duration(rand.Intn(10)+1) * time.Second / 100)
42 bar.Increment()
4343 }
4444
4545 p.Stop()
3434
3535 func main() {
3636
37 p := mpb.New(mpb.WithWidth(64), mpb.WithBeforeRenderFunc(sortByProgressFunc()))
38
37 var wg sync.WaitGroup
38 p := mpb.New(
39 mpb.WithWaitGroup(&wg),
40 mpb.WithBeforeRenderFunc(sortByProgressFunc()),
41 )
3942 total := 100
4043 numBars := 3
41 var wg sync.WaitGroup
4244 wg.Add(numBars)
4345
4446 for i := 0; i < numBars; i++ {
6668 }()
6769 }
6870
69 wg.Wait()
7071 p.Stop()
7172 fmt.Println("stop")
7273 }
1717 func main() {
1818
1919 var wg sync.WaitGroup
20 p := mpb.New()
20 p := mpb.New(mpb.WithWaitGroup(&wg))
2121 wg.Add(totalBars)
2222
2323 for i := 0; i < totalBars; i++ {
4444 }()
4545 }
4646
47 wg.Wait()
4847 p.Stop()
4948 fmt.Println("stop")
5049 }
22 import (
33 "io"
44 "io/ioutil"
5 "sync"
56 "time"
67 "unicode/utf8"
78
1112 // ProgressOption is a function option which changes the default behavior of
1213 // progress pool, if passed to mpb.New(...ProgressOption)
1314 type ProgressOption func(*pConf)
15
16 // WithWaitGroup provides means to have a single joint point.
17 // If *sync.WaitGroup is provided, you can safely call just p.Stop()
18 // without calling Wait() on provided *sync.WaitGroup.
19 // Makes sense when there are more than one bar to render.
20 func WithWaitGroup(wg *sync.WaitGroup) ProgressOption {
21 return func(c *pConf) {
22 c.ewg = wg
23 }
24 }
1425
1526 // WithWidth overrides default width 80
1627 func WithWidth(w int) ProgressOption {
2424 width int
2525 format string
2626 rr time.Duration
27 ewg *sync.WaitGroup
2728 cw *cwriter.Writer
2829 ticker *time.Ticker
2930 beforeRender BeforeRender
4546
4647 // Progress represents the container that renders Progress bars
4748 type Progress struct {
48 // WaitGroup for internal rendering sync
49 // wg for internal rendering sync
4950 wg *sync.WaitGroup
51 // External wg
52 ewg *sync.WaitGroup
5053
5154 // quit channel to request p.server to quit
5255 quit chan struct{}
7376 }
7477
7578 p := &Progress{
79 ewg: conf.ewg,
7680 wg: new(sync.WaitGroup),
7781 done: make(chan struct{}),
7882 ops: make(chan func(*pConf)),
137141 }
138142 }
139143
140 // Stop shutdowns Progress' goroutine.
141 // Should be called only after each bar's work done, i.e. bar has reached its
142 // 100 %. It is NOT for cancelation. Use WithContext or WithCancel for
143 // cancelation purposes.
144 // Stop is a way to gracefully shutdown mpb's rendering goroutine.
145 // It is NOT for cancelation (use mpb.WithContext for cancelation purposes).
146 // If *sync.WaitGroup has been provided via mpb.WithWaitGroup(), its Wait()
147 // method will be called first.
144148 func (p *Progress) Stop() {
149 if p.ewg != nil {
150 p.ewg.Wait()
151 }
145152 select {
146153 case <-p.quit:
147154 return