Codebase list golang-github-vbauerster-mpb / d73c8d6
pass state around Vladimir Bauer 9 years ago
1 changed file(s) with 75 addition(s) and 73 deletion(s). Raw diff Collapse all Expand all
00 package mpb
11
22 import (
3 "fmt"
34 "io"
45 "math"
56 "sync"
2021
2122 // Bar represents a progress Bar
2223 type Bar struct {
23 stateReqCh chan chan state
24 widthCh chan int
25 formatCh chan string
26 etaAlphaCh chan float64
24 stateReqCh chan state
2725 incrCh chan int64
28 trimLeftCh chan bool
29 trimRightCh chan bool
30 refillCh chan *refill
3126 dCommandCh chan *dCommandData
3227 flushedCh chan struct{}
3328 removeReqCh chan struct{}
3429 completeReqCh chan struct{}
3530 done chan struct{}
31 cancel <-chan struct{}
3632
3733 // follawing are used after (*Bar.done) is closed
3834 width int
4541 Completed bool
4642 Total int64
4743 Current int64
48 IncrAmount int64
4944 StartTime time.Time
5045 TimeElapsed time.Duration
5146 TimePerItemEstimate time.Duration
6863 etaAlpha float64
6964 total int64
7065 current int64
71 incrAmount int64
7266 trimLeftSpace bool
7367 trimRightSpace bool
7468 completed bool
8478
8579 func newBar(id int, total int64, wg *sync.WaitGroup, conf *userConf) *Bar {
8680 b := &Bar{
87 stateReqCh: make(chan chan state),
88 widthCh: make(chan int),
89 formatCh: make(chan string),
90 etaAlphaCh: make(chan float64),
81 width: conf.width,
82 stateReqCh: make(chan state),
9183 incrCh: make(chan int64, 1),
92 trimLeftCh: make(chan bool),
93 trimRightCh: make(chan bool),
94 refillCh: make(chan *refill),
9584 dCommandCh: make(chan *dCommandData),
9685 flushedCh: make(chan struct{}, 1),
9786 removeReqCh: make(chan struct{}),
9887 completeReqCh: make(chan struct{}),
9988 done: make(chan struct{}),
100 }
101 go b.server(id, total, wg, conf)
89 cancel: conf.cancel,
90 }
91
92 s := state{
93 id: id,
94 total: total,
95 width: conf.width,
96 etaAlpha: 0.25,
97 }
98
99 if total <= 0 {
100 s.simpleSpinner = getSpinner()
101 } else {
102 s.updateFormat(conf.format)
103 }
104
105 go b.server(wg, s)
102106 return b
103107 }
104108
107111 if n < 2 || isClosed(b.done) {
108112 return b
109113 }
110 b.widthCh <- n
114 s := <-b.stateReqCh
115 s.width = n
116 b.stateReqCh <- s
111117 return b
112118 }
113119
116122 if isClosed(b.done) {
117123 return b
118124 }
119 b.trimLeftCh <- true
125 // b.trimLeftCh <- true
126 s := <-b.stateReqCh
127 s.trimLeftSpace = true
128 b.stateReqCh <- s
120129 return b
121130 }
122131
125134 if isClosed(b.done) {
126135 return b
127136 }
128 b.trimRightCh <- true
137 // b.trimRightCh <- true
138 s := <-b.stateReqCh
139 s.trimRightSpace = true
140 b.stateReqCh <- s
129141 return b
130142 }
131143
134146 if utf8.RuneCountInString(format) != numFmtRunes || isClosed(b.done) {
135147 return b
136148 }
137 b.formatCh <- format
149 s := <-b.stateReqCh
150 s.updateFormat(format)
151 b.stateReqCh <- s
138152 return b
139153 }
140154
145159 if isClosed(b.done) {
146160 return b
147161 }
148 b.etaAlphaCh <- a
162 s := <-b.stateReqCh
163 s.etaAlpha = a
164 b.stateReqCh <- s
149165 return b
150166 }
151167
168184 return
169185 }
170186 b.Incr(n)
171 b.refillCh <- &refill{r, int64(n)}
187 // b.refillCh <- &refill{r, int64(n)}
188 s := <-b.stateReqCh
189 s.refill = &refill{r, int64(n)}
190 b.stateReqCh <- s
172191 }
173192
174193 // GetAppenders returns slice of appender DecoratorFunc
257276 if isClosed(b.done) {
258277 return b.state
259278 }
260 ch := make(chan state)
261 b.stateReqCh <- ch
262 return <-ch
263 }
264
265 func (b *Bar) server(id int, total int64, wg *sync.WaitGroup, conf *userConf) {
279 return <-b.stateReqCh
280 }
281
282 func (b *Bar) server(wg *sync.WaitGroup, s state) {
266283 var incrStartTime time.Time
267 barState := state{
268 id: id,
269 total: total,
270 width: conf.width,
271 etaAlpha: 0.25,
272 }
273 if total <= 0 {
274 barState.simpleSpinner = getSpinner()
275 } else {
276 barState.updateFormat(conf.format)
277 }
284
278285 defer func() {
279 b.stop(&barState, conf.width)
286 // b.stop(&barState, conf.width)
287 b.stop(&s)
280288 wg.Done()
289 fmt.Printf("Exited bar %d\n", s.id)
281290 }()
291
282292 for {
283293 select {
284 case barState.incrAmount = <-b.incrCh:
285 if barState.current == 0 {
294 case b.stateReqCh <- s:
295 case s = <-b.stateReqCh:
296 case amount := <-b.incrCh:
297 if s.current == 0 {
286298 incrStartTime = time.Now()
287 barState.startTime = incrStartTime
299 s.startTime = incrStartTime
288300 }
289 n := barState.current + barState.incrAmount
290 if total > 0 && n > total {
291 barState.current = total
292 barState.completed = true
301 n := s.current + amount
302 if s.total > 0 && n > s.total {
303 s.current = s.total
304 s.completed = true
293305 break // break out of select
294306 }
295 barState.timeElapsed = time.Since(barState.startTime)
296 barState.updateTimePerItemEstimate(incrStartTime)
297 if n == total {
298 barState.completed = true
307 s.timeElapsed = time.Since(s.startTime)
308 s.updateTimePerItemEstimate(incrStartTime, amount)
309 if n == s.total {
310 s.completed = true
299311 }
300 barState.current = n
312 s.current = n
301313 incrStartTime = time.Now()
302314 case data := <-b.dCommandCh:
303315 switch data.action {
304316 case dAppend:
305 barState.appendFuncs = append(barState.appendFuncs, data.f)
317 s.appendFuncs = append(s.appendFuncs, data.f)
306318 case dAppendZero:
307 barState.appendFuncs = nil
319 s.appendFuncs = nil
308320 case dPrepend:
309 barState.prependFuncs = append(barState.prependFuncs, data.f)
321 s.prependFuncs = append(s.prependFuncs, data.f)
310322 case dPrependZero:
311 barState.prependFuncs = nil
323 s.prependFuncs = nil
312324 }
313 case ch := <-b.stateReqCh:
314 ch <- barState
315 case format := <-b.formatCh:
316 barState.updateFormat(format)
317 case barState.width = <-b.widthCh:
318 case barState.refill = <-b.refillCh:
319 case barState.trimLeftSpace = <-b.trimLeftCh:
320 case barState.trimRightSpace = <-b.trimRightCh:
321325 case <-b.flushedCh:
322 if barState.completed {
326 if s.completed {
323327 return
324328 }
325329 case <-b.completeReqCh:
326330 return
327331 case <-b.removeReqCh:
328332 return
329 case <-conf.cancel:
333 case <-b.cancel:
330334 return
331335 }
332336 }
333337 }
334338
335 func (b *Bar) stop(s *state, width int) {
339 func (b *Bar) stop(s *state) {
336340 b.state = *s
337 b.width = width
338341 close(b.done)
339342 }
340343
373376 }
374377 }
375378
376 func (s *state) updateTimePerItemEstimate(incrStartTime time.Time) {
379 func (s *state) updateTimePerItemEstimate(incrStartTime time.Time, amount int64) {
377380 lastBlockTime := time.Since(incrStartTime) // shorthand for time.Now().Sub(t)
378 lastItemEstimate := float64(lastBlockTime) / float64(s.incrAmount)
381 lastItemEstimate := float64(lastBlockTime) / float64(amount)
379382 s.timePerItem = time.Duration((s.etaAlpha * lastItemEstimate) + (1-s.etaAlpha)*float64(s.timePerItem))
380383 }
381384
497500 Completed: s.completed,
498501 Total: s.total,
499502 Current: s.current,
500 IncrAmount: s.incrAmount,
501503 StartTime: s.startTime,
502504 TimeElapsed: s.timeElapsed,
503505 TimePerItemEstimate: s.timePerItem,