diff --git a/bar.go b/bar.go index f968f1f..8a73d23 100644 --- a/bar.go +++ b/bar.go @@ -69,37 +69,21 @@ complete bool } -func newBar(container *Progress, bs *bState) (*Bar, func()) { +func newBar(container *Progress, bs *bState) *Bar { ctx, cancel := context.WithCancel(container.ctx) - operateState := make(chan func(*bState)) - done := make(chan struct{}) - serve := func() { - defer container.bwg.Done() - for { - select { - case op := <-operateState: - op(bs) - case <-ctx.Done(): - bs.aborted = !bs.completed - bs.decoratorShutdownNotify() - close(done) - return - } - } - } bar := &Bar{ priority: bs.priority, hasEwma: len(bs.ewmaDecorators) != 0, frameCh: make(chan *frame, 1), - operateState: operateState, - done: done, + operateState: make(chan func(*bState)), + done: make(chan struct{}), container: container, - bs: bs, cancel: cancel, } - return bar, serve + go bar.serve(ctx, bs) + return bar } // ProxyReader wraps r with metrics required for progress tracking. @@ -311,6 +295,22 @@ return <-result case <-b.done: return b.bs.completed + } +} + +func (b *Bar) serve(ctx context.Context, bs *bState) { + defer b.container.bwg.Done() + for { + select { + case op := <-b.operateState: + op(bs) + case <-ctx.Done(): + bs.aborted = !bs.completed + bs.decoratorShutdownNotify() + b.bs = bs + close(b.done) + return + } } } diff --git a/progress.go b/progress.go index 97c6180..62a8eb7 100644 --- a/progress.go +++ b/progress.go @@ -49,14 +49,9 @@ externalRefresh <-chan interface{} renderDelay <-chan struct{} shutdownNotifier chan struct{} - queueBars map[*Bar]queueBar + queueBars map[*Bar]*Bar output io.Writer debugOut io.Writer -} - -type queueBar struct { - bar *Bar - serve func() } // New creates new Progress container instance. It's not possible to @@ -72,7 +67,7 @@ s := &pState{ bHeap: priorityQueue{}, rr: prr, - queueBars: make(map[*Bar]queueBar), + queueBars: make(map[*Bar]*Bar), output: os.Stdout, } @@ -123,13 +118,12 @@ select { case p.operateState <- func(ps *pState) { bs := ps.makeBarState(total, filler, options...) - bar, serve := newBar(p, bs) + bar := newBar(p, bs) if bs.afterBar != nil { - ps.queueBars[bs.afterBar] = queueBar{bar, serve} + ps.queueBars[bs.afterBar] = bar } else { heap.Push(&ps.bHeap, bar) ps.heapUpdated = true - go serve() } ps.idCount++ result <- bar @@ -293,9 +287,8 @@ var toDrop bool if qb, ok := s.queueBars[b]; ok { delete(s.queueBars, b) - qb.bar.priority = b.priority - heap.Push(&s.bHeap, qb.bar) - go qb.serve() + qb.priority = b.priority + heap.Push(&s.bHeap, qb) toDrop = true } else if s.popCompleted && !b.bs.noPop { frame := bm[b]