Codebase list golang-github-vbauerster-mpb / fb9c166
don't expose internal wg Vladimir Bauer 9 years ago
5 changed file(s) with 35 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
2020 Following is the simplest use case:
2121
2222 ```go
23 // No need to initialize sync.WaitGroup, as it is initialized implicitly
24 p := mpb.New() // Star mpb container
23 var wg sync.WaitGroup
24 p := mpb.New() // Star mpb's rendering goroutine
2525 for i := 0; i < 3; i++ {
26 p.Wg.Add(1) // add wg counter
26 wg.Add(1) // add wg delta
2727 name := fmt.Sprintf("Bar#%d:", i)
2828 bar := p.AddBar(100).PrependName(name, len(name)).AppendPercentage()
2929 go func() {
30 defer wg.Done()
3031 // you can p.AddBar() here, but ordering will be non deterministic
3132 for i := 0; i < 100; i++ {
3233 time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
3435 }
3536 }()
3637 }
37 p.WaitAndStop() // Wait for goroutines to finish
38 wg.Wait() // Wait for goroutines to finish
39 p.Stop() // Stop mpb's rendering goroutine
3840 // p.AddBar(1) // panic: you cannot reuse p, create new one!
3941 fmt.Println("finish")
4042 ```
66 "net/http"
77 "os"
88 "path/filepath"
9 "sync"
910
1011 "github.com/vbauerster/mpb"
1112 )
1617 url1 := "https://homebrew.bintray.com/bottles/youtube-dl-2016.12.12.sierra.bottle.tar.gz"
1718 url2 := "https://homebrew.bintray.com/bottles/libtiff-4.0.7.sierra.bottle.tar.gz"
1819
20 var wg sync.WaitGroup
1921 p := mpb.New().SetWidth(60)
2022
2123 for i, url := range [...]string{url1, url2} {
22 p.Wg.Add(1) // if you omit this line, main will return without waiting for download goroutines
24 wg.Add(1)
2325 name := fmt.Sprintf("url%d:", i+1)
24 go download(p, name, url)
26 go download(&wg, p, name, url)
2527 }
2628
27 p.WaitAndStop()
29 wg.Wait()
30 p.Stop()
2831 fmt.Println("Finished")
2932 }
3033
31 func download(p *mpb.Progress, name, url string) {
34 func download(wg *sync.WaitGroup, p *mpb.Progress, name, url string) {
35 defer wg.Done()
3236 resp, err := http.Get(url)
3337 if err != nil {
3438 log.Printf("%s: %v", name, err)
3535 defer dest.Close()
3636
3737 p := mpb.New().SetWidth(64)
38 // if you omit the following line, download will complete fine, but rendering bar
39 // may not complete, thus better always use even in single thread.
40 p.Wg.Add(1)
4138
4239 bar := p.AddBar(int(size)).PrependCounters(mpb.UnitBytes, 20).AppendETA()
4340
4744 // and copy from reader, ignoring errors
4845 io.Copy(dest, reader)
4946
50 p.WaitAndStop()
47 p.Stop() // if you omit this line, rendering bars goroutine will quit early
5148 fmt.Println("Finished")
5249 }
22 import (
33 "fmt"
44 "math/rand"
5 "sync"
56 "time"
67
78 "github.com/vbauerster/mpb"
89 )
910
1011 func main() {
11 // No need to initialize sync.WaitGroup, as it is initialized implicitly
12 p := mpb.New() // Star mpb container
12 var wg sync.WaitGroup
13 p := mpb.New() // Star mpb's rendering goroutine
1314 for i := 0; i < 3; i++ {
14 p.Wg.Add(1) // add wg counter
15 wg.Add(1) // add wg delta
1516 name := fmt.Sprintf("Bar#%d:", i)
1617 bar := p.AddBar(100).PrependName(name, len(name)).AppendPercentage()
1718 go func() {
19 defer wg.Done()
1820 // you can p.AddBar() here, but ordering will be non deterministic
1921 for i := 0; i < 100; i++ {
2022 time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
2224 }
2325 }()
2426 }
25 p.WaitAndStop() // Wait for goroutines to finish
27 wg.Wait() // Wait for goroutines to finish
28 p.Stop() // Stop mpb's rendering goroutine
2629 // p.AddBar(1) // panic: you cannot reuse p, create new one!
2730 fmt.Println("finish")
2831 }
3030
3131 // Progress represents the container that renders Progress bars
3232 type Progress struct {
33 Wg *sync.WaitGroup
33 // WaitGroup for internal rendering sync
34 wg *sync.WaitGroup
3435
3536 out io.Writer
3637 width int
3738 sort SortType
38 // stopped bool
3939
4040 op chan *operation
4141 rrChangeReqCh chan time.Duration
5959 outChangeReqCh: make(chan io.Writer),
6060 countReqCh: make(chan chan int),
6161 allDone: make(chan struct{}),
62 Wg: new(sync.WaitGroup),
62 wg: new(sync.WaitGroup),
6363 }
6464 go p.server(cwriter.New(os.Stdout), time.NewTicker(rr*time.Millisecond))
6565 return p
9898
9999 // AddBar creates a new progress bar and adds to the container
100100 func (p *Progress) AddBar(total int) *Bar {
101 bar := newBar(total, p.width, p.Wg)
102 p.op <- &operation{opBarAdd, bar, nil}
101 result := make(chan bool)
102 bar := newBar(total, p.width, p.wg)
103 p.op <- &operation{opBarAdd, bar, result}
104 if <-result {
105 p.wg.Add(1)
106 }
103107 return bar
104108 }
105109
117121 return <-respCh
118122 }
119123
120 // WaitAndStop stops listening
121 func (p *Progress) WaitAndStop() {
124 // Stop waits for bars to finish rendering and stops the rendering goroutine
125 func (p *Progress) Stop() {
122126 if !p.isAllDone() {
123127 close(p.allDone)
124 p.Wg.Wait()
128 p.wg.Wait()
125129 close(p.op)
126130 }
127131 }
142146 switch op.kind {
143147 case opBarAdd:
144148 bars = append(bars, op.bar)
149 op.result <- true
145150 case opBarRemove:
146151 var ok bool
147152 for i, b := range bars {
164169 sort.Sort(SortableBarSlice(bars))
165170 }
166171 for _, b := range bars {
167 // cannot parallel this, because order matters
168172 fmt.Fprintln(cw, b)
169173 }
170174 cw.Flush()