Codebase list golang-github-vbauerster-mpb / e3d6220
Refactor: widthSyncer Vladimir Bauer 8 years ago
6 changed file(s) with 50 addition(s) and 50 deletion(s). Raw diff Collapse all Expand all
6161 timeElapsed time.Duration
6262 blockStartTime time.Time
6363 timePerItem time.Duration
64 appendFuncs []decor.DecoratorFunc
65 prependFuncs []decor.DecoratorFunc
64 aDecorators []decor.DecoratorFunc
65 pDecorators []decor.DecoratorFunc
6666 refill *refill
6767 bufP, bufB, bufA *bytes.Buffer
6868 panicMsg string
112112 func (b *Bar) RemoveAllPrependers() {
113113 select {
114114 case b.operateState <- func(s *bState) {
115 s.prependFuncs = nil
115 s.pDecorators = nil
116116 }:
117117 case <-b.done:
118118 }
122122 func (b *Bar) RemoveAllAppenders() {
123123 select {
124124 case b.operateState <- func(s *bState) {
125 s.appendFuncs = nil
125 s.aDecorators = nil
126126 }:
127127 case <-b.done:
128128 }
195195 func (b *Bar) NumOfAppenders() int {
196196 result := make(chan int, 1)
197197 select {
198 case b.operateState <- func(s *bState) { result <- len(s.appendFuncs) }:
199 return <-result
200 case <-b.done:
201 return len(b.cacheState.appendFuncs)
198 case b.operateState <- func(s *bState) { result <- len(s.aDecorators) }:
199 return <-result
200 case <-b.done:
201 return len(b.cacheState.aDecorators)
202202 }
203203 }
204204
206206 func (b *Bar) NumOfPrependers() int {
207207 result := make(chan int, 1)
208208 select {
209 case b.operateState <- func(s *bState) { result <- len(s.prependFuncs) }:
210 return <-result
211 case <-b.done:
212 return len(b.cacheState.prependFuncs)
209 case b.operateState <- func(s *bState) { result <- len(s.pDecorators) }:
210 return <-result
211 case <-b.done:
212 return len(b.cacheState.pDecorators)
213213 }
214214 }
215215
306306 }
307307 }
308308
309 func (b *Bar) render(tw int, prependWs, appendWs *widthSync) <-chan *toRenderReader {
309 func (b *Bar) render(tw int, pSyncer, aSyncer *widthSyncer) <-chan *toRenderReader {
310310 ch := make(chan *toRenderReader, 1)
311311
312312 go func() {
317317 // recovering if external decorators panic
318318 if p := recover(); p != nil {
319319 s.panicMsg = fmt.Sprintf("b#%02d panic: %v\n", s.id, p)
320 s.prependFuncs = nil
321 s.appendFuncs = nil
320 s.pDecorators = nil
321 s.aDecorators = nil
322322 s.completed = true
323323 r = strings.NewReader(s.panicMsg)
324324 }
325325 ch <- &toRenderReader{r, s.completed, s.removed}
326326 }()
327 s.draw(tw, prependWs, appendWs)
327 s.draw(tw, pSyncer, aSyncer)
328328 r = io.MultiReader(s.bufP, s.bufB, s.bufA)
329329 }:
330330 case <-b.done:
333333 if s.panicMsg != "" {
334334 r = strings.NewReader(s.panicMsg)
335335 } else {
336 s.draw(tw, prependWs, appendWs)
336 s.draw(tw, pSyncer, aSyncer)
337337 r = io.MultiReader(s.bufP, s.bufB, s.bufA)
338338 }
339339 ch <- &toRenderReader{r, s.completed, s.removed}
350350 s.blockStartTime = next
351351 }
352352
353 func (s *bState) draw(termWidth int, prependWs, appendWs *widthSync) {
353 func (s *bState) draw(termWidth int, pSyncer, aSyncer *widthSyncer) {
354354 if termWidth <= 0 {
355355 termWidth = s.width
356356 }
359359
360360 // render prepend functions to the left of the bar
361361 s.bufP.Reset()
362 for i, f := range s.prependFuncs {
363 s.bufP.WriteString(f(stat, prependWs.Listen[i], prependWs.Result[i]))
362 for i, f := range s.pDecorators {
363 s.bufP.WriteString(f(stat, pSyncer.Accumulator[i], pSyncer.Distributor[i]))
364364 }
365365
366366 if !s.trimLeftSpace {
373373 s.bufA.WriteByte(' ')
374374 }
375375
376 for i, f := range s.appendFuncs {
377 s.bufA.WriteString(f(stat, appendWs.Listen[i], appendWs.Result[i]))
376 for i, f := range s.aDecorators {
377 s.bufA.WriteString(f(stat, aSyncer.Accumulator[i], aSyncer.Distributor[i]))
378378 }
379379
380380 prependCount := utf8.RuneCount(s.bufP.Bytes())
88 // AppendDecorators let you inject decorators to the bar's right side
99 func AppendDecorators(appenders ...decor.DecoratorFunc) BarOption {
1010 return func(s *bState) {
11 s.appendFuncs = append(s.appendFuncs, appenders...)
11 s.aDecorators = append(s.aDecorators, appenders...)
1212 }
1313 }
1414
1515 // PrependDecorators let you inject decorators to the bar's left side
1616 func PrependDecorators(prependers ...decor.DecoratorFunc) BarOption {
1717 return func(s *bState) {
18 s.prependFuncs = append(s.prependFuncs, prependers...)
18 s.pDecorators = append(s.pDecorators, prependers...)
1919 }
2020 }
2121
126126 res[i] = make(chan string, 1)
127127 go func(s step, ch chan string) {
128128 defer wg.Done()
129 ch <- dfn(s.stat, ws.Listen[0], ws.Result[0])
129 ch <- dfn(s.stat, ws.Accumulator[0], ws.Distributor[0])
130130 }(columnCase[i], res[i])
131131 }
132132 wg.Wait()
177177 },
178178 }
179179
180 prependWs := newWidthSync(nil, 1, 0)
181 appendWs := newWidthSync(nil, 1, 0)
180 prependWs := newWidthSyncer(nil, 1, 0)
181 appendWs := newWidthSyncer(nil, 1, 0)
182182 for termWidth, cases := range testSuite {
183183 for name, tc := range cases {
184184 s := newTestState()
00 package mpb
11
2 var NewWidthSync = newWidthSync
2 var NewWidthSync = newWidthSyncer
5050 shutdownNotifier chan struct{}
5151 cancel <-chan struct{}
5252 }
53 widthSync struct {
54 Listen []chan int
55 Result []chan int
53 widthSyncer struct {
54 // Public for easy testing
55 Accumulator []chan int
56 Distributor []chan int
5657 }
5758 toRenderSnapshot struct {
5859 bar *Bar
154155 <-p.done
155156 }
156157
157 func newWidthSync(timeout <-chan struct{}, numBars, numColumn int) *widthSync {
158 ws := &widthSync{
159 Listen: make([]chan int, numColumn),
160 Result: make([]chan int, numColumn),
158 func newWidthSyncer(timeout <-chan struct{}, numBars, numColumn int) *widthSyncer {
159 ws := &widthSyncer{
160 Accumulator: make([]chan int, numColumn),
161 Distributor: make([]chan int, numColumn),
161162 }
162163 for i := 0; i < numColumn; i++ {
163 ws.Listen[i] = make(chan int, numBars)
164 ws.Result[i] = make(chan int, numBars)
164 ws.Accumulator[i] = make(chan int, numBars)
165 ws.Distributor[i] = make(chan int, numBars)
165166 }
166167 for i := 0; i < numColumn; i++ {
167 go func(listenCh <-chan int, resultCh chan<- int) {
168 defer close(resultCh)
168 go func(accumulator <-chan int, discharger chan<- int) {
169 defer close(discharger)
169170 widths := make([]int, 0, numBars)
170171 loop:
171172 for {
172173 select {
173 case w := <-listenCh:
174 case w := <-accumulator:
174175 widths = append(widths, w)
175176 if len(widths) == numBars {
176177 break loop
184185 }
185186 result := max(widths)
186187 for i := 0; i < len(widths); i++ {
187 resultCh <- result
188 discharger <- result
188189 }
189 }(ws.Listen[i], ws.Result[i])
190 }(ws.Accumulator[i], ws.Distributor[i])
190191 }
191192 return ws
192193 }
193194
194195 func (s *pState) writeAndFlush(tw, numP, numA int) (err error) {
195 wSyncTimeout := make(chan struct{})
196 timeout := make(chan struct{})
197 pSyncer := newWidthSyncer(timeout, s.bHeap.Len(), numP)
198 aSyncer := newWidthSyncer(timeout, s.bHeap.Len(), numA)
196199 time.AfterFunc(s.rr-s.rr/12, func() {
197 close(wSyncTimeout)
200 close(timeout)
198201 })
199202
200 prependWs := newWidthSync(wSyncTimeout, s.bHeap.Len(), numP)
201 appendWs := newWidthSync(wSyncTimeout, s.bHeap.Len(), numA)
202
203 for _, trs := range s.renderByPriority(tw, prependWs, appendWs) {
203 for _, trs := range s.renderByPriority(tw, pSyncer, aSyncer) {
204204 r := <-trs.pipe
205205 _, err = s.cw.ReadFrom(r)
206206 if !trs.bar.completed && r.toComplete {
222222 return
223223 }
224224
225 func (s *pState) renderByPriority(tw int, prependWs, appendWs *widthSync) []*toRenderSnapshot {
225 func (s *pState) renderByPriority(tw int, pSyncer, aSyncer *widthSyncer) []*toRenderSnapshot {
226226 slice := make([]*toRenderSnapshot, 0, s.bHeap.Len())
227227 for s.bHeap.Len() > 0 {
228228 b := heap.Pop(s.bHeap).(*Bar)
229229 defer heap.Push(s.bHeap, b)
230230 slice = append(slice, &toRenderSnapshot{
231231 bar: b,
232 pipe: b.render(tw, prependWs, appendWs),
232 pipe: b.render(tw, pSyncer, aSyncer),
233233 })
234234 }
235235 return slice