After a research on how mutexes work, a mutex bcame embedded. And locks should be invoke from outside.
This commit is contained in:
parent
2facf9662a
commit
baad7da10d
@ -62,6 +62,8 @@ func main() {
|
|||||||
log.Printf("Failed to fetch last N songs: %s\n", err)
|
log.Printf("Failed to fetch last N songs: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lstnrs.RLock()
|
||||||
|
defer lstnrs.Unlock()
|
||||||
web.Index(¤tSong, lst, *songListLen, lstnrs, r).Render(context.Background(), w)
|
web.Index(¤tSong, lst, *songListLen, lstnrs, r).Render(context.Background(), w)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -112,6 +114,8 @@ func main() {
|
|||||||
switch <-sysSignal {
|
switch <-sysSignal {
|
||||||
case os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT, syscall.SIGSEGV:
|
case os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT, syscall.SIGSEGV:
|
||||||
if currentSong.Artist != "" {
|
if currentSong.Artist != "" {
|
||||||
|
lstnrs.Lock()
|
||||||
|
defer lstnrs.Unlock()
|
||||||
currentSong.Listeners, currentSong.PeakListeners = lstnrs.Reset()
|
currentSong.Listeners, currentSong.PeakListeners = lstnrs.Reset()
|
||||||
if err := stats.Add(¤tSong); err != nil {
|
if err := stats.Add(¤tSong); err != nil {
|
||||||
log.Println("failed to save a current song during a shutdown:", err)
|
log.Println("failed to save a current song during a shutdown:", err)
|
||||||
|
@ -42,8 +42,12 @@ func (dj *DJHandlers) ListenersUpdateIcecast(w http.ResponseWriter, r *http.Requ
|
|||||||
|
|
||||||
switch r.FormValue("action") {
|
switch r.FormValue("action") {
|
||||||
case "listener_add":
|
case "listener_add":
|
||||||
|
dj.listeners.Lock()
|
||||||
_ = dj.listeners.Inc()
|
_ = dj.listeners.Inc()
|
||||||
|
dj.listeners.Unlock()
|
||||||
case "listener_remove":
|
case "listener_remove":
|
||||||
|
dj.listeners.Lock()
|
||||||
|
defer dj.listeners.Unlock()
|
||||||
if _, err := dj.listeners.Dec(); err != nil {
|
if _, err := dj.listeners.Dec(); err != nil {
|
||||||
log.Println("DJHandlers.ListenersUpdateIcecast:", err)
|
log.Println("DJHandlers.ListenersUpdateIcecast:", err)
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
@ -107,7 +111,9 @@ func (dj *DJHandlers) PlaylistNext(w http.ResponseWriter, _ *http.Request) {
|
|||||||
newSong.Artist = "Nothing to play. Playing a fallback: " + newSong.Artist
|
newSong.Artist = "Nothing to play. Playing a fallback: " + newSong.Artist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dj.listeners.Lock()
|
||||||
dj.curSong.Listeners, dj.curSong.PeakListeners = dj.listeners.Reset()
|
dj.curSong.Listeners, dj.curSong.PeakListeners = dj.listeners.Reset()
|
||||||
|
dj.listeners.Unlock()
|
||||||
|
|
||||||
if dj.curSong.Artist != "" && !strings.Contains(dj.curSong.Artist, "no artist tag") &&
|
if dj.curSong.Artist != "" && !strings.Contains(dj.curSong.Artist, "no artist tag") &&
|
||||||
!strings.Contains(dj.curSong.Artist, "No title tag") {
|
!strings.Contains(dj.curSong.Artist, "No title tag") {
|
||||||
@ -131,6 +137,8 @@ func (dj *DJHandlers) Status(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Println("failed to fetch last n songs:", err)
|
log.Println("failed to fetch last n songs:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dj.listeners.RLock()
|
||||||
|
defer dj.listeners.Unlock()
|
||||||
err = json.NewEncoder(w).Encode(&struct {
|
err = json.NewEncoder(w).Encode(&struct {
|
||||||
Current *radio.Song `json:"current_song,omitempty"`
|
Current *radio.Song `json:"current_song,omitempty"`
|
||||||
Listeners int64 `json:"listeners"`
|
Listeners int64 `json:"listeners"`
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
// ListenerCounter stores the current, overall and peak numbers of listeners.
|
// ListenerCounter stores the current, overall and peak numbers of listeners.
|
||||||
type ListenerCounter struct {
|
type ListenerCounter struct {
|
||||||
mutex sync.RWMutex
|
sync.RWMutex
|
||||||
current, peak int64
|
current, peak int64
|
||||||
overall, cur_peak int64
|
overall, cur_peak int64
|
||||||
}
|
}
|
||||||
@ -21,36 +21,26 @@ func NewListenerCounter() *ListenerCounter {
|
|||||||
|
|
||||||
// Current returns a number of current listeners.
|
// Current returns a number of current listeners.
|
||||||
func (l *ListenerCounter) Current() int64 {
|
func (l *ListenerCounter) Current() int64 {
|
||||||
l.mutex.RLock()
|
|
||||||
defer l.mutex.RUnlock()
|
|
||||||
return l.current
|
return l.current
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peak returns a peak number of listeners.
|
// Peak returns a peak number of listeners.
|
||||||
func (l *ListenerCounter) Peak() int64 {
|
func (l *ListenerCounter) Peak() int64 {
|
||||||
l.mutex.RLock()
|
|
||||||
defer l.mutex.RUnlock()
|
|
||||||
return l.peak
|
return l.peak
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentPeak returns a peak number of listeners for a currently playing song.
|
// CurrentPeak returns a peak number of listeners for a currently playing song.
|
||||||
func (l *ListenerCounter) CurrentPeak() int64 {
|
func (l *ListenerCounter) CurrentPeak() int64 {
|
||||||
l.mutex.RLock()
|
|
||||||
defer l.mutex.RUnlock()
|
|
||||||
return l.cur_peak
|
return l.cur_peak
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overall returns an overall number of listeners for a currently playing song.
|
// Overall returns an overall number of listeners for a currently playing song.
|
||||||
func (l *ListenerCounter) Overall() int64 {
|
func (l *ListenerCounter) Overall() int64 {
|
||||||
l.mutex.RLock()
|
|
||||||
defer l.mutex.RUnlock()
|
|
||||||
return l.overall
|
return l.overall
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inc increments by 1 a current number of listeners and updates a peak number.
|
// Inc increments by 1 a current number of listeners and updates a peak number.
|
||||||
func (l *ListenerCounter) Inc() int64 {
|
func (l *ListenerCounter) Inc() int64 {
|
||||||
l.mutex.Lock()
|
|
||||||
defer l.mutex.Unlock()
|
|
||||||
if l.current == math.MaxInt64 {
|
if l.current == math.MaxInt64 {
|
||||||
// We panic here because if this will ever happen, then something's going certainly wrong.
|
// We panic here because if this will ever happen, then something's going certainly wrong.
|
||||||
panic("a current number of listeners exceeded MaxInt64")
|
panic("a current number of listeners exceeded MaxInt64")
|
||||||
@ -72,8 +62,6 @@ func (l *ListenerCounter) Inc() int64 {
|
|||||||
// Dec decrements by 1 a current number of listeners. An error will occur if
|
// Dec decrements by 1 a current number of listeners. An error will occur if
|
||||||
// a resulting number is less than 0.
|
// a resulting number is less than 0.
|
||||||
func (l *ListenerCounter) Dec() (int64, error) {
|
func (l *ListenerCounter) Dec() (int64, error) {
|
||||||
l.mutex.Lock()
|
|
||||||
defer l.mutex.Unlock()
|
|
||||||
if l.current == 0 {
|
if l.current == 0 {
|
||||||
return l.current, errors.New("an attempt to decrement a number of current listeners down to less than 0")
|
return l.current, errors.New("an attempt to decrement a number of current listeners down to less than 0")
|
||||||
}
|
}
|
||||||
@ -84,8 +72,6 @@ func (l *ListenerCounter) Dec() (int64, error) {
|
|||||||
// Reset current peak and overall listeners for a song that is playing.
|
// Reset current peak and overall listeners for a song that is playing.
|
||||||
// And return its values.
|
// And return its values.
|
||||||
func (l *ListenerCounter) Reset() (overall, peak int64) {
|
func (l *ListenerCounter) Reset() (overall, peak int64) {
|
||||||
l.mutex.Lock()
|
|
||||||
defer l.mutex.Unlock()
|
|
||||||
peak = l.cur_peak
|
peak = l.cur_peak
|
||||||
l.cur_peak = l.current
|
l.cur_peak = l.current
|
||||||
overall = l.overall
|
overall = l.overall
|
||||||
@ -94,8 +80,6 @@ func (l *ListenerCounter) Reset() (overall, peak int64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *ListenerCounter) MarshalJSON() ([]byte, error) {
|
func (l *ListenerCounter) MarshalJSON() ([]byte, error) {
|
||||||
l.mutex.RLock()
|
|
||||||
defer l.mutex.RUnlock()
|
|
||||||
return json.Marshal(&struct {
|
return json.Marshal(&struct {
|
||||||
Current int64 `json:"current"`
|
Current int64 `json:"current"`
|
||||||
Peak int64 `json:"peak"`
|
Peak int64 `json:"peak"`
|
||||||
|
Loading…
Reference in New Issue
Block a user