Codebase list golang-github-vbauerster-mpb / 02ef807
shutdown refresh listener goroutine first then p.serve Vladimir Bauer 3 years ago
3 changed file(s) with 46 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
4343 rmOnComplete bool
4444 noPop bool
4545 autoRefresh bool
46 manualRefresh bool
4746 aDecorators []decor.Decorator
4847 pDecorators []decor.Decorator
4948 averageDecorators []decor.AverageDecorator
457456 // one hour for example and bar completes within a few minutes p.Wait()
458457 // will wait for one hour. This call helps to avoid unnecessary waiting.
459458 go b.tryEarlyRefresh(s.refreshCh)
460 } else if !s.manualRefresh {
459 } else {
461460 b.cancel()
462461 }
463462 }
4040 // Refresh will occur upon receive value from provided ch.
4141 func WithManualRefresh(ch <-chan interface{}) ContainerOption {
4242 return func(s *pState) {
43 s.manualRefresh = true
44 go func(refreshCh chan<- time.Time, done <-chan struct{}) {
45 for {
46 select {
47 case x := <-ch:
48 if t, ok := x.(time.Time); ok {
49 refreshCh <- t
50 } else {
51 refreshCh <- time.Now()
52 }
53 case <-done:
54 return
55 }
56 }
57 }(s.refreshCh, s.ctx.Done())
43 s.manualRC = ch
5844 }
5945 }
6046
4343 refreshRate time.Duration
4444 reqWidth int
4545 popCompleted bool
46 manualRefresh bool
4746 autoRefresh bool
4847 renderDelay <-chan struct{}
48 manualRC <-chan interface{}
4949 shutdownNotifier chan<- interface{}
5050 queueBars map[*Bar]*Bar
5151 output io.Writer
8383 }
8484 }
8585
86 go s.hm.run()
87
88 cw := cwriter.New(s.output)
89 if (cw.IsTerminal() || s.autoRefresh) && !s.manualRefresh {
90 s.autoRefresh = true
91 go s.newTicker(s.renderDelay != nil)
92 } else {
93 s.autoRefresh = false
94 }
95
9686 p := &Progress{
9787 uwg: s.uwg,
9888 operateState: make(chan func(*pState)),
9989 interceptIO: make(chan func(io.Writer)),
100 done: ctx.Done(),
10190 cancel: cancel,
91 }
92
93 cw := cwriter.New(s.output)
94 if s.manualRC != nil {
95 done := make(chan struct{})
96 p.done = done
97 s.autoRefresh = false
98 go s.manualRefreshListener(done)
99 } else if cw.IsTerminal() || s.autoRefresh {
100 done := make(chan struct{})
101 p.done = done
102 s.autoRefresh = true
103 go s.autoRefreshListener(done)
104 } else {
105 p.done = s.ctx.Done()
106 s.autoRefresh = false
102107 }
103108
104109 p.pwg.Add(1)
105110 go p.serve(s, cw)
111 go s.hm.run()
106112 return p
107113 }
108114
266272 }
267273 }
268274
269 func (s *pState) newTicker(delay bool) {
270 if delay {
275 func (s pState) autoRefreshListener(done chan struct{}) {
276 if s.renderDelay != nil {
271277 <-s.renderDelay
272278 }
273279 ticker := time.NewTicker(s.refreshRate)
277283 case t := <-ticker.C:
278284 s.refreshCh <- t
279285 case <-s.ctx.Done():
286 close(done)
287 return
288 }
289 }
290 }
291
292 func (s pState) manualRefreshListener(done chan struct{}) {
293 for {
294 select {
295 case x := <-s.manualRC:
296 if t, ok := x.(time.Time); ok {
297 s.refreshCh <- t
298 } else {
299 s.refreshCh <- time.Now()
300 }
301 case <-s.ctx.Done():
302 close(done)
280303 return
281304 }
282305 }
384407
385408 func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOption) *bState {
386409 bs := &bState{
387 id: s.idCount,
388 priority: s.idCount,
389 reqWidth: s.reqWidth,
390 total: total,
391 filler: filler,
392 refreshCh: s.refreshCh,
393 autoRefresh: s.autoRefresh,
394 manualRefresh: s.manualRefresh,
410 id: s.idCount,
411 priority: s.idCount,
412 reqWidth: s.reqWidth,
413 total: total,
414 filler: filler,
415 refreshCh: s.refreshCh,
416 autoRefresh: s.autoRefresh,
395417 }
396418
397419 if total > 0 {