Codebase list golang-github-vbauerster-mpb / 1b433b4
Better Stop() Vladimir Bauer 9 years ago
1 changed file(s) with 23 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
00 package mpb
11
22 import (
3 "errors"
43 "fmt"
54 "io"
65 "os"
1110
1211 "github.com/vbauerster/mpb/cwriter"
1312 )
14
15 // ErrCallAfterStop thrown by panic, if Progress methods like (*Progress).AddBar()
16 // are called after (*Progress).Stop() has been called
17 var ErrCallAfterStop = errors.New("method call on stopped Progress instance")
1813
1914 // default RefreshRate
2015 var rr = 100 * time.Millisecond
6762 // WaitGroup for internal rendering sync
6863 wg *sync.WaitGroup
6964
70 done chan struct{}
71 userConfCh chan userConf
72 bCommandCh chan *bCommandData
73 barCountCh chan int
74 beforeStopCh chan struct{}
65 done chan struct{}
66 userConfCh chan userConf
67 bCommandCh chan *bCommandData
68 barCountCh chan int
69 stopReqCh chan struct{}
7570
7671 // follawing is used after (*Progress.done) is closed
7772 conf userConf
8277 // If you don't plan to cancel, it is safe to feed with nil
8378 func New() *Progress {
8479 p := &Progress{
85 wg: new(sync.WaitGroup),
86 done: make(chan struct{}),
87 userConfCh: make(chan userConf),
88 bCommandCh: make(chan *bCommandData),
89 barCountCh: make(chan int),
90 beforeStopCh: make(chan struct{}),
80 wg: new(sync.WaitGroup),
81 done: make(chan struct{}),
82 userConfCh: make(chan userConf),
83 bCommandCh: make(chan *bCommandData),
84 barCountCh: make(chan int),
85 stopReqCh: make(chan struct{}),
9186 }
9287 go p.server(userConf{
9388 width: pwidth,
212207 // 100 %. It is NOT for cancelation. Use WithContext or WithCancel for
213208 // cancelation purposes.
214209 func (p *Progress) Stop() {
215 if isClosed(p.done) {
210 select {
211 case <-p.done:
216212 return
217 }
218 p.wg.Wait()
219
220 p.beforeStopCh <- struct{}{}
221 // wait for p.server to quit
222 <-p.done
213 default:
214 p.wg.Wait() // wait for all bars to quit
215 p.stopReqCh <- struct{}{}
216 <-p.done // wait for p.server to quit
217 }
223218 }
224219
225220 func (p *Progress) getConf() userConf {
288283 }
289284 case p.barCountCh <- len(bars):
290285 case <-conf.ticker.C:
291 if conf.cancel != nil && isClosed(conf.cancel) {
286 // stop ticking if cancel requested
287 select {
288 case <-conf.cancel:
292289 conf.ticker.Stop()
293290 break
291 default:
294292 }
295293
296294 numBars := len(bars)
329327 for _, b := range bars {
330328 b.flushed()
331329 }
332 case <-p.beforeStopCh:
330 case <-p.stopReqCh:
333331 for _, b := range bars {
334332 if b.GetStatistics().Total <= 0 {
335 fmt.Println("completing the bar: ", b)
336333 b.Completed()
337334 }
338335 }
391388 return ch
392389 }
393390
394 // isClosed check if ch closed
395 // caution see: http://www.tapirgames.com/blog/golang-channel-closing
396 func isClosed(ch <-chan struct{}) bool {
397 select {
398 case <-ch:
399 return true
400 default:
401 return false
402 }
403 }
404
405391 func max(slice []int) int {
406392 max := slice[0]
407393