package core import ( "sync" ) type StatCounter interface { Value() int64 Set(int64) int64 Add(int64) int64 } type StatManager interface { Feature RegisterCounter(string) (StatCounter, error) GetCounter(string) StatCounter } // GetOrRegisterStatCounter tries to get the StatCounter first. If not exist, it then tries to create a new counter. func GetOrRegisterStatCounter(m StatManager, name string) (StatCounter, error) { counter := m.GetCounter(name) if counter != nil { return counter, nil } return m.RegisterCounter(name) } type syncStatManager struct { sync.RWMutex StatManager } func (s *syncStatManager) Start() error { s.RLock() defer s.RUnlock() if s.StatManager == nil { return nil } return s.StatManager.Start() } func (s *syncStatManager) Close() error { s.RLock() defer s.RUnlock() if s.StatManager == nil { return nil } return s.StatManager.Close() } func (s *syncStatManager) RegisterCounter(name string) (StatCounter, error) { s.RLock() defer s.RUnlock() if s.StatManager == nil { return nil, newError("StatManager not set.") } return s.StatManager.RegisterCounter(name) } func (s *syncStatManager) GetCounter(name string) StatCounter { s.RLock() defer s.RUnlock() if s.StatManager == nil { return nil } return s.StatManager.GetCounter(name) } func (s *syncStatManager) Set(m StatManager) { if m == nil { return } s.Lock() defer s.Unlock() if s.StatManager != nil { s.StatManager.Close() // nolint: errcheck } s.StatManager = m }