From 9ef0771389af941f8b38570c07435b1859cecedc Mon Sep 17 00:00:00 2001 From: "Alexander \"Arav\" Andreev" Date: Thu, 9 May 2024 20:30:17 +0400 Subject: [PATCH] SongList struct was removed. A Song struct got UpdateMaxListeners() and IncListeners() methods. A mutex was Introduced for it. A Listeners field to store overall number of listeners during a song playing was introduced as well. A comment for the Song struct was removed. --- internal/radio/song.go | 100 +++++++++++------------------------------ 1 file changed, 26 insertions(+), 74 deletions(-) diff --git a/internal/radio/song.go b/internal/radio/song.go index cddf89e..bb47e64 100644 --- a/internal/radio/song.go +++ b/internal/radio/song.go @@ -6,18 +6,35 @@ import ( "time" ) -// Song stores artist and title of a song, a timestamp of when it started, its -// duration, and a maximum number of listeners. type Song struct { + mutex sync.Mutex Artist string Title string Duration time.Duration - MaxListeners int + Listeners int64 + MaxListeners int64 StartAt time.Time } +func (s *Song) UpdateMaxListeners(listeners int64) { + s.mutex.Lock() + if listeners > s.MaxListeners { + s.MaxListeners = listeners + } + s.mutex.Unlock() +} + +// IncListeners increments by one an overall amount of listeners of this song. +func (s *Song) IncListeners() { + s.mutex.Lock() + s.Listeners++ + s.mutex.Unlock() +} + // DurationString returns song's duration as a string formatted as [H:]M:SS. func (s *Song) DurationString() string { + s.mutex.Lock() + defer s.mutex.Unlock() if s.Duration.Hours() >= 1 { return time.UnixMilli(s.Duration.Milliseconds()).Format("3:4:05") } @@ -25,85 +42,20 @@ func (s *Song) DurationString() string { } func (s *Song) MarshalJSON() ([]byte, error) { + s.mutex.Lock() + defer s.mutex.Unlock() return json.Marshal(&struct { Artist string `json:"artist"` Title string `json:"title"` - DurationMill int64 `json:"duration_msec"` - MaxListeners int `json:"listeners"` + DurationMill int64 `json:"duration_msec,omitempty"` + Listeners int64 `json:"listeners"` + MaxListeners int64 `json:"max_listeners"` StartAt string `json:"start_at"` }{ Artist: s.Artist, Title: s.Title, DurationMill: s.Duration.Milliseconds(), + Listeners: s.Listeners, MaxListeners: s.MaxListeners, StartAt: s.StartAt.UTC().Format(time.RFC3339)}) } - -// SongList holds a currently playing song and a list of previously played ones -// with a maximal length of maxLen. -type SongList struct { - mutex sync.RWMutex - current Song - lastSongs []Song - maxLen int -} - -// NewSongList returns a new SongList with a maximal length set with maxLen. -func NewSongList(maxLen int) *SongList { - return &SongList{maxLen: maxLen, lastSongs: make([]Song, 0, maxLen)} -} - -// Add a new song that is currently playing and update a list. -func (sl *SongList) Add(newSong Song) { - sl.mutex.Lock() - defer sl.mutex.Unlock() - - if sl.current.StartAt.Year() == 1 { - sl.current = newSong - return - } - - if len(sl.lastSongs) == sl.maxLen { - sl.lastSongs = append(sl.lastSongs[1:], sl.current) - } else { - sl.lastSongs = append(sl.lastSongs, sl.current) - } - sl.current = newSong -} - -// Current returns a currently playing song or nil if it isn't set yet. -func (sl *SongList) Current() *Song { - sl.mutex.RLock() - defer sl.mutex.RUnlock() - if sl.current.StartAt.Year() == 1 { - return nil - } - return &Song{ - Artist: sl.current.Artist, - Title: sl.current.Title, - Duration: sl.current.Duration, - MaxListeners: sl.current.MaxListeners, - StartAt: sl.current.StartAt} -} - -// UpdateCurrentMaxListeners checks and updates a maximal number of listeners -// for a current song. -func (sl *SongList) UpdateCurrentMaxListeners(listeners int) { - sl.mutex.Lock() - defer sl.mutex.Unlock() - if listeners > sl.current.MaxListeners { - sl.current.MaxListeners = listeners - } -} - -// List returns a list of lastly played songs. -func (sl *SongList) List() []Song { - sl.mutex.RLock() - defer sl.mutex.RUnlock() - return sl.lastSongs -} - -// MaxLen returns a maximal length of a song list. -func (sl *SongList) MaxLen() int { - return sl.maxLen -}