github.com/vmware/govmomi@v0.51.0/vim25/progress/aggregator.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package progress 6 7 import "sync" 8 9 type Aggregator struct { 10 downstream Sinker 11 upstream chan (<-chan Report) 12 13 done chan struct{} 14 w sync.WaitGroup 15 } 16 17 func NewAggregator(s Sinker) *Aggregator { 18 a := &Aggregator{ 19 downstream: s, 20 upstream: make(chan (<-chan Report)), 21 22 done: make(chan struct{}), 23 } 24 25 a.w.Add(1) 26 go a.loop() 27 28 return a 29 } 30 31 func (a *Aggregator) loop() { 32 defer a.w.Done() 33 34 dch := a.downstream.Sink() 35 defer close(dch) 36 37 for { 38 select { 39 case uch := <-a.upstream: 40 // Drain upstream channel 41 for e := range uch { 42 dch <- e 43 } 44 case <-a.done: 45 return 46 } 47 } 48 } 49 50 func (a *Aggregator) Sink() chan<- Report { 51 ch := make(chan Report) 52 a.upstream <- ch 53 return ch 54 } 55 56 // Done marks the aggregator as done. No more calls to Sink() may be made and 57 // the downstream progress report channel will be closed when Done() returns. 58 func (a *Aggregator) Done() { 59 close(a.done) 60 a.w.Wait() 61 }