Codebase list golang-github-vbauerster-mpb / f260885
bar refactoring Vladimir Bauer 9 years ago
3 changed file(s) with 64 addition(s) and 65 deletion(s). Raw diff Collapse all Expand all
3535 leftEnd byte
3636 rightEnd byte
3737
38 incrCh chan int
39 redrawReqCh chan chan []byte
40 progressReqCh chan chan int
41 decoratorCh chan *decorator
42 flushedCh chan struct{}
43 stopCh chan struct{}
44 done chan struct{}
38 incrCh chan int
39 redrawReqCh chan chan []byte
40 statusReqCh chan chan int
41 decoratorCh chan *decorator
42 flushedCh chan struct{}
43 stopCh chan struct{}
44 done chan struct{}
4545 }
4646
4747 type Statistics struct {
5555
5656 func newBar(total, width int, wg *sync.WaitGroup) *Bar {
5757 b := &Bar{
58 fill: '=',
59 empty: '-',
60 tip: '>',
61 leftEnd: '[',
62 rightEnd: ']',
63 alpha: 0.25,
64 total: total,
65 width: width,
66 incrCh: make(chan int),
67 redrawReqCh: make(chan chan []byte),
68 progressReqCh: make(chan chan int),
69 decoratorCh: make(chan *decorator),
70 flushedCh: make(chan struct{}),
71 stopCh: make(chan struct{}),
72 done: make(chan struct{}),
58 fill: '=',
59 empty: '-',
60 tip: '>',
61 leftEnd: '[',
62 rightEnd: ']',
63 alpha: 0.25,
64 total: total,
65 width: width,
66 incrCh: make(chan int),
67 redrawReqCh: make(chan chan []byte),
68 statusReqCh: make(chan chan int),
69 decoratorCh: make(chan *decorator),
70 flushedCh: make(chan struct{}),
71 stopCh: make(chan struct{}),
72 done: make(chan struct{}),
7373 }
7474 go b.server(wg)
7575 return b
139139 }
140140
141141 func (b *Bar) Incr(n int) {
142 if !b.IsCompleted() {
142 if !b.isDone() {
143143 b.incrCh <- n
144144 }
145145 }
151151 }
152152 }
153153
154 func (b *Bar) IsCompleted() bool {
155 select {
156 case <-b.done:
157 return true
158 default:
159 return false
160 }
154 func (b *Bar) InProgress() bool {
155 return !b.isDone()
161156 }
162157
163158 func (b *Bar) PrependFunc(f DecoratorFunc) *Bar {
233228 var timeElapsed time.Duration
234229 var appendFuncs []DecoratorFunc
235230 var prependFuncs []DecoratorFunc
236 var done bool
231 var completed bool
237232 var current int
238233 for {
239234 select {
240235 case i := <-b.incrCh:
241236 n := current + i
242 // fmt.Fprintf(os.Stderr, "n = %+v\n", n)
243237 if n > b.total {
244238 current = b.total
245 done = true
239 completed = true
246240 break
247241 }
248242 timeElapsed = time.Since(timeStarted)
249243 tpie = calcTimePerItemEstimate(tpie, blockStartTime, b.alpha, i)
250244 blockStartTime = time.Now()
251245 current = n
252 if current == b.total && !done {
253 done = true
246 if current == b.total && !completed {
247 completed = true
254248 }
255249 case d := <-b.decoratorCh:
256250 switch d.kind {
262256 case respCh := <-b.redrawReqCh:
263257 stat := &Statistics{b.total, current, timeElapsed, tpie}
264258 respCh <- b.draw(stat, buf, appendFuncs, prependFuncs)
265 case respCh := <-b.progressReqCh:
259 case respCh := <-b.statusReqCh:
266260 respCh <- int(100 * float64(current) / float64(b.total))
267261 case <-b.flushedCh:
268 if done && !b.IsCompleted() {
269 // fmt.Fprintln(os.Stderr, "flushedCh: wg.Done")
262 if completed && !b.isDone() {
270263 close(b.done)
271264 wg.Done()
272265 }
273266 case <-b.stopCh:
274 // fmt.Fprintln(os.Stderr, "received stop signal")
275 if !done {
276 // fmt.Fprintln(os.Stderr, "closing done chan: done = false")
267 if !completed {
277268 close(b.done)
278269 wg.Done()
279270 }
314305 return buf
315306 }
316307
308 func (b *Bar) isDone() bool {
309 select {
310 case <-b.done:
311 return true
312 default:
313 return false
314 }
315 }
316
317 func (b *Bar) status() int {
318 respCh := make(chan int)
319 b.statusReqCh <- respCh
320 return <-respCh
321 }
322
323 // SortableBarSlice satisfies sort interface
324 type SortableBarSlice []*Bar
325
326 func (p SortableBarSlice) Len() int { return len(p) }
327
328 func (p SortableBarSlice) Less(i, j int) bool { return p[i].status() < p[j].status() }
329
330 func (p SortableBarSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
331
317332 func calcTimePerItemEstimate(tpie time.Duration, blockStartTime time.Time, alpha float64, items int) time.Duration {
318333 lastBlockTime := time.Since(blockStartTime)
319334 lastItemEstimate := float64(lastBlockTime) / float64(items)
320335 return time.Duration((alpha * lastItemEstimate) + (1-alpha)*float64(tpie))
321336 }
322
323 func (b *Bar) progress() int {
324 respCh := make(chan int)
325 b.progressReqCh <- respCh
326 return <-respCh
327 }
328
329 type SortableBarSlice []*Bar
330
331 func (p SortableBarSlice) Len() int { return len(p) }
332
333 func (p SortableBarSlice) Less(i, j int) bool { return p[i].progress() < p[j].progress() }
334
335 func (p SortableBarSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
22 import (
33 "fmt"
44 "math/rand"
5 "runtime"
65 "time"
76
8 "github.com/vbauerster/uiprogress"
7 "github.com/vbauerster/mpb"
98 )
109
1110 const (
1413 )
1514
1615 func main() {
17 runtime.GOMAXPROCS(runtime.NumCPU())
18 decor := func(s *uiprogress.Statistics) string {
19 str := fmt.Sprintf("%d/%d", s.Completed, s.Total)
16 decor := func(s *mpb.Statistics) string {
17 str := fmt.Sprintf("%d/%d", s.Current, s.Total)
2018 return fmt.Sprintf("%-7s", str)
2119 }
2220
23 p := uiprogress.New()
21 p := mpb.New()
2422 bar := p.AddBar(totalItem).AppendETA().PrependFunc(decor)
2523
2624 blockSize := rand.Intn(maxBlockSize) + 1
27 // Fallowing will hang, in order not to hang
28 // use !bar.IsCompleted in loop condition
29 // for i := 0; !bar.IsCompleted(); i += blockSize {
25 // Fallowing will hang, to prevent
26 // use bar.InProgress() bool method
27 // for i := 0; bar.InProgress(); i += blockSize {
3028 for i := 0; i < totalItem; i += blockSize {
3129 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
3230 bar.Incr(blockSize)
1313
1414 func main() {
1515 decor := func(s *mpb.Statistics) string {
16 str := fmt.Sprintf("%d/%d", s.Completed, s.Total)
16 str := fmt.Sprintf("%d/%d", s.Current, s.Total)
1717 return fmt.Sprintf("%-7s", str)
1818 }
1919