Codebase list golang-github-vbauerster-mpb / 205b1af
first p.wg.Wait then p.beforeStopCh <- struct{}{} Vladimir Bauer 9 years ago
3 changed file(s) with 120 addition(s) and 123 deletion(s). Raw diff Collapse all Expand all
00 package mpb
11
22 import (
3 "fmt"
34 "io"
45 "math"
6 "os"
57 "sync"
68 "time"
79 "unicode/utf8"
2022
2123 // Bar represents a progress Bar
2224 type Bar struct {
23 stateReqCh chan state
24 incrCh chan incrReq
25 dCommandCh chan *dCommandData
25 stateReqCh chan state
26 incrCh chan incrReq
27 // dCommandCh chan *dCommandData
2628 flushedCh chan struct{}
2729 removeReqCh chan struct{}
2830 completedCh chan struct{}
8385
8486 func newBar(id int, total int64, wg *sync.WaitGroup, conf *userConf) *Bar {
8587 b := &Bar{
86 width: conf.width,
87 stateReqCh: make(chan state),
88 incrCh: make(chan incrReq),
89 dCommandCh: make(chan *dCommandData),
88 width: conf.width,
89 stateReqCh: make(chan state),
90 incrCh: make(chan incrReq),
91 // dCommandCh: make(chan *dCommandData),
9092 flushedCh: make(chan struct{}),
9193 removeReqCh: make(chan struct{}),
9294 completedCh: make(chan struct{}),
113115
114116 // SetWidth overrides width of individual bar
115117 func (b *Bar) SetWidth(n int) *Bar {
116 if n < 2 || isClosed(b.done) {
118 if n < 2 {
117119 return b
118120 }
119 s := <-b.stateReqCh
120 s.width = n
121 b.stateReqCh <- s
121 b.updateState(func(s *state) {
122 s.width = n
123 })
122124 return b
123125 }
124126
125127 // TrimLeftSpace removes space befor LeftEnd charater
126128 func (b *Bar) TrimLeftSpace() *Bar {
127 if isClosed(b.done) {
128 return b
129 }
130 // b.trimLeftCh <- true
131 s := <-b.stateReqCh
132 s.trimLeftSpace = true
133 b.stateReqCh <- s
129 b.updateState(func(s *state) {
130 s.trimLeftSpace = true
131 })
134132 return b
135133 }
136134
137135 // TrimRightSpace removes space after RightEnd charater
138136 func (b *Bar) TrimRightSpace() *Bar {
139 if isClosed(b.done) {
140 return b
141 }
142 // b.trimRightCh <- true
143 s := <-b.stateReqCh
144 s.trimRightSpace = true
145 b.stateReqCh <- s
137 b.updateState(func(s *state) {
138 s.trimRightSpace = true
139 })
146140 return b
147141 }
148142
149143 // Format overrides format of individual bar
150144 func (b *Bar) Format(format string) *Bar {
151 if utf8.RuneCountInString(format) != numFmtRunes || isClosed(b.done) {
145 if utf8.RuneCountInString(format) != numFmtRunes {
152146 return b
153147 }
154 s := <-b.stateReqCh
155 s.updateFormat(format)
156 b.stateReqCh <- s
148 b.updateState(func(s *state) {
149 s.updateFormat(format)
150 })
157151 return b
158152 }
159153
161155 // Defaults to 0.25
162156 // Normally you shouldn't touch this
163157 func (b *Bar) SetEtaAlpha(a float64) *Bar {
164 if isClosed(b.done) {
165 return b
166 }
167 s := <-b.stateReqCh
168 s.etaAlpha = a
169 b.stateReqCh <- s
170 return b
158 b.updateState(func(s *state) {
159 s.etaAlpha = a
160 })
161 return b
162 }
163
164 // PrependFunc prepends DecoratorFunc
165 func (b *Bar) PrependFunc(f DecoratorFunc) *Bar {
166 b.updateState(func(s *state) {
167 s.prependFuncs = append(s.prependFuncs, f)
168 })
169 return b
170 }
171
172 // AppendFunc appends DecoratorFunc
173 func (b *Bar) AppendFunc(f DecoratorFunc) *Bar {
174 b.updateState(func(s *state) {
175 s.appendFuncs = append(s.appendFuncs, f)
176 })
177 return b
178 }
179
180 // RemoveAllPrependers removes all prepend functions
181 func (b *Bar) RemoveAllPrependers() {
182 b.updateState(func(s *state) {
183 s.prependFuncs = nil
184 })
185 }
186
187 // RemoveAllAppenders removes all append functions
188 func (b *Bar) RemoveAllAppenders() {
189 b.updateState(func(s *state) {
190 s.appendFuncs = nil
191 })
171192 }
172193
173194 // ProxyReader wrapper for io operations, like io.Copy
228249 // Can be used as condition in for loop
229250 func (b *Bar) InProgress() bool {
230251 return !isClosed(b.done)
231 }
232
233 // PrependFunc prepends DecoratorFunc
234 func (b *Bar) PrependFunc(f DecoratorFunc) *Bar {
235 if isClosed(b.done) {
236 return b
237 }
238 b.dCommandCh <- &dCommandData{dPrepend, f}
239 return b
240 }
241
242 // RemoveAllPrependers removes all prepend functions
243 func (b *Bar) RemoveAllPrependers() {
244 if isClosed(b.done) {
245 return
246 }
247 b.dCommandCh <- &dCommandData{dPrependZero, nil}
248 }
249
250 // AppendFunc appends DecoratorFunc
251 func (b *Bar) AppendFunc(f DecoratorFunc) *Bar {
252 if isClosed(b.done) {
253 return b
254 }
255 b.dCommandCh <- &dCommandData{dAppend, f}
256 return b
257 }
258
259 // RemoveAllAppenders removes all append functions
260 func (b *Bar) RemoveAllAppenders() {
261 if isClosed(b.done) {
262 return
263 }
264 b.dCommandCh <- &dCommandData{dAppendZero, nil}
265252 }
266253
267254 // Completed signals to the bar, that process has been completed.
275262 }
276263 }
277264
265 func (b *Bar) flushed() {
266 select {
267 case b.flushedCh <- struct{}{}:
268 case <-b.done:
269 fmt.Fprintf(os.Stderr, "flushedCh abort: %d\n", b.state.id)
270 return
271 }
272 }
273
274 func (b *Bar) remove() {
275 select {
276 case b.removeReqCh <- struct{}{}:
277 case <-b.done:
278 return
279 }
280 }
281
278282 func (b *Bar) getState() state {
279283 select {
280284 case s := <-b.stateReqCh:
284288 }
285289 }
286290
291 func (b *Bar) updateState(cb func(s *state)) {
292 s := b.getState()
293 cb(&s)
294 select {
295 case b.stateReqCh <- s:
296 case <-b.done:
297 return
298 }
299 }
300
287301 func (b *Bar) server(wg *sync.WaitGroup, s state) {
288302 var incrStartTime time.Time
289303
290304 defer func() {
291305 b.state = s
292306 wg.Done()
293 // fmt.Printf("Exited bar %d\n", s.id)
294307 close(b.done)
308 fmt.Fprintf(os.Stderr, "Exited bar %d\n", s.id)
295309 }()
296310
297311 for {
317331 s.current = n
318332 s.refill = r.refill
319333 incrStartTime = time.Now()
320 case data := <-b.dCommandCh:
321 switch data.action {
322 case dAppend:
323 s.appendFuncs = append(s.appendFuncs, data.f)
324 case dAppendZero:
325 s.appendFuncs = nil
326 case dPrepend:
327 s.prependFuncs = append(s.prependFuncs, data.f)
328 case dPrependZero:
329 s.prependFuncs = nil
330 }
331334 case <-b.flushedCh:
332335 if s.completed {
336 fmt.Fprintln(os.Stderr, "completed")
333337 return
334338 }
335339 case <-b.completedCh:
340344 case <-b.cancel:
341345 return
342346 }
343 }
344 }
345
346 func (b *Bar) flushed() {
347 select {
348 case b.flushedCh <- struct{}{}:
349 case <-b.done:
350 return
351 }
352 }
353
354 func (b *Bar) remove() {
355 select {
356 case b.removeReqCh <- struct{}{}:
357 case <-b.done:
358 return
359347 }
360348 }
361349
2020 DextraSpace
2121 )
2222
23 type decoratorAction uint
24
25 const (
26 dAppend decoratorAction = iota
27 dPrepend
28 dAppendZero
29 dPrependZero
30 )
23 // type decoratorAction uint
24
25 // const (
26 // dAppend decoratorAction = iota
27 // dPrepend
28 // dAppendZero
29 // dPrependZero
30 // )
3131
3232 // DecoratorFunc is a function that can be prepended and appended to the progress bar
3333 type DecoratorFunc func(s *Statistics, myWidth chan<- int, maxWidth <-chan int) string
3434
35 type dCommandData struct {
36 action decoratorAction
37 f DecoratorFunc
38 }
35 // type dCommandData struct {
36 // action decoratorAction
37 // f DecoratorFunc
38 // }
3939
4040 // PrependName prepends name argument to the bar.
4141 // The conf argument defines the formatting properties
7171 userConf chan userConf
7272 bCommandCh chan *bCommandData
7373 barCountReqCh chan chan int
74 beforeStop chan struct{}
74 beforeStopCh chan struct{}
7575 }
7676
7777 // New creates new Progress instance, which will orchestrate bars rendering
8484 userConf: make(chan userConf),
8585 bCommandCh: make(chan *bCommandData),
8686 barCountReqCh: make(chan chan int),
87 beforeStop: make(chan struct{}),
87 beforeStopCh: make(chan struct{}),
8888 }
8989 go p.server(userConf{
9090 width: pwidth,
247247 if isClosed(p.done) {
248248 return
249249 }
250 p.beforeStop <- struct{}{}
250 // fmt.Println("inside p.Stop")
251251 p.wg.Wait()
252 close(p.bCommandCh)
252
253 p.beforeStopCh <- struct{}{}
254 fmt.Println("signal sent to p.beforeStopCh")
255 <-p.done
256 fmt.Println("p.done closed")
253257 }
254258
255259 // server monitors underlying channels and renders any progress bars
256260 func (p *Progress) server(conf userConf) {
257261
258262 defer func() {
259 conf.ticker.Stop()
260 close(p.done)
263 // fmt.Println("exiting p.server")
264 // conf.ticker.Stop()
261265 if conf.shutdownNotifier != nil {
262266 close(conf.shutdownNotifier)
263267 }
268 // fmt.Println("about to close(p.done)")
269 close(p.done)
264270 }()
265271
266272 recoverFn := func(ch chan []byte) {
279285 select {
280286 case p.userConf <- conf:
281287 case conf = <-p.userConf:
282 case data, ok := <-p.bCommandCh:
283 if !ok {
284 return
285 }
288 case data := <-p.bCommandCh:
286289 switch data.action {
287290 case bAdd:
288291 bars = append(bars, data.bar)
302305 case respCh := <-p.barCountReqCh:
303306 respCh <- len(bars)
304307 case <-conf.ticker.C:
308 if conf.cancel != nil && isClosed(conf.cancel) {
309 conf.ticker.Stop()
310 break
311 }
312
305313 numBars := len(bars)
306
307314 if numBars == 0 {
308315 break
309316 }
339346 for _, b := range bars {
340347 b.flushed()
341348 }
342 case <-p.beforeStop:
349 case <-p.beforeStopCh:
350 // fmt.Println("case beforeStopCh")
343351 for _, b := range bars {
344352 if b.GetStatistics().Total <= 0 {
353 fmt.Println("completing the bar: ", b)
345354 b.Completed()
346355 }
347356 }
348 case <-conf.cancel:
357 conf.ticker.Stop()
349358 return
350359 }
351360 }