github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/controller/operators/openshift/synctracker.go (about) 1 package openshift 2 3 import ( 4 "context" 5 "fmt" 6 "sync" 7 8 configv1 "github.com/openshift/api/config/v1" 9 "sigs.k8s.io/controller-runtime/pkg/event" 10 ) 11 12 func NewSyncTracker(syncCh <-chan error, co *configv1.ClusterOperator) *SyncTracker { 13 return &SyncTracker{ 14 syncCh: syncCh, 15 events: make(chan event.GenericEvent), 16 co: co, 17 } 18 } 19 20 type SyncTracker struct { 21 syncCh <-chan error 22 events chan event.GenericEvent 23 mutex sync.RWMutex 24 once sync.Once 25 26 co *configv1.ClusterOperator 27 totalSyncs, successfulSyncs int 28 } 29 30 func (s *SyncTracker) Start(ctx context.Context) error { 31 if s.syncCh == nil || s.events == nil || s.co == nil { 32 return fmt.Errorf("invalid %T fields", s) 33 } 34 35 var err error 36 s.once.Do(func() { 37 err = s.start(ctx) 38 }) 39 40 return err 41 } 42 43 func (s *SyncTracker) start(ctx context.Context) error { 44 defer close(s.events) 45 for { 46 select { 47 case <-ctx.Done(): 48 return nil 49 case err, ok := <-s.syncCh: 50 if !ok { 51 // Channel is closed 52 return nil 53 } 54 55 s.addSync(err == nil) 56 } 57 s.events <- event.GenericEvent{Object: s.co} 58 } 59 } 60 61 func (s *SyncTracker) Events() <-chan event.GenericEvent { 62 return s.events 63 } 64 65 func (s *SyncTracker) addSync(successful bool) { 66 s.mutex.Lock() 67 defer s.mutex.Unlock() 68 69 s.totalSyncs++ 70 if successful { 71 s.successfulSyncs++ 72 } 73 } 74 75 func (s *SyncTracker) TotalSyncs() int { 76 s.mutex.RLock() 77 defer s.mutex.RUnlock() 78 79 return s.totalSyncs 80 } 81 82 func (s *SyncTracker) SuccessfulSyncs() int { 83 s.mutex.RLock() 84 defer s.mutex.RUnlock() 85 86 return s.successfulSyncs 87 }