package radio import ( "encoding/json" "errors" "fmt" "math" "sync" ) // ListenerCounter stores the current and peak numbers of listeners. type ListenerCounter struct { mut sync.Mutex current, peak int } // NewListenerCounter returns a new ListenerCounter struct instance. func NewListenerCounter() *ListenerCounter { return &ListenerCounter{} } // Current returns a number of current listeners. func (l *ListenerCounter) Current() int { l.mut.Lock() defer l.mut.Unlock() return l.current } // Current returns a number of peak listeners. func (l *ListenerCounter) Peak() int { l.mut.Lock() defer l.mut.Unlock() return l.peak } // Inc increments by 1 a current number of listeners and updates a peak number. func (l *ListenerCounter) Inc() int { l.mut.Lock() defer l.mut.Unlock() if l.current == math.MaxInt { // We panic here because if this will ever happen, then something's going certainly wrong. panic(fmt.Sprint("a current number of listeners exceeded MaxInt which is", math.MaxInt)) } l.current++ if l.current > l.peak { l.peak = l.current } return l.current } // Dec decrements by 1 a current number of listeners. An error will occur if // a resulting number is less than 0. func (l *ListenerCounter) Dec() (int, error) { l.mut.Lock() defer l.mut.Unlock() if l.current == 0 { return l.current, errors.New("an attempt to decrement a number of current listeners down to less than 0") } l.current-- return l.current, nil } func (l *ListenerCounter) MarshalJSON() ([]byte, error) { l.mut.Lock() defer l.mut.Unlock() return json.Marshal(&struct { Current int `json:"current"` Peak int `json:"peak"` }{ Current: l.current, Peak: l.peak}) }