feat(ui): add Now Playing panel for admins (#4209)
* feat(ui): add Now Playing panel and integrate now playing count updates Signed-off-by: Deluan <deluan@navidrome.org> * fix: check return value in test to satisfy linter * fix: format React code with prettier * fix: resolve race condition in play tracker test * fix: log error when fetching now playing data fails Signed-off-by: Deluan <deluan@navidrome.org> * feat(ui): refactor Now Playing panel with new components and error handling Signed-off-by: Deluan <deluan@navidrome.org> * fix(ui): adjust padding and height in Now Playing panel for improved layout Signed-off-by: Deluan <deluan@navidrome.org> * fix(cache): add automatic cleanup to prevent goroutine leak on cache garbage collection Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Vendored
+25
-1
@@ -1,8 +1,10 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
@@ -17,6 +19,8 @@ type SimpleCache[K comparable, V any] interface {
|
||||
GetWithLoader(key K, loader func(key K) (V, time.Duration, error)) (V, error)
|
||||
Keys() []K
|
||||
Values() []V
|
||||
Len() int
|
||||
OnExpiration(fn func(K, V)) func()
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
@@ -39,9 +43,17 @@ func NewSimpleCache[K comparable, V any](options ...Options) SimpleCache[K, V] {
|
||||
}
|
||||
|
||||
c := ttlcache.New[K, V](opts...)
|
||||
return &simpleCache[K, V]{
|
||||
cache := &simpleCache[K, V]{
|
||||
data: c,
|
||||
}
|
||||
go cache.data.Start()
|
||||
|
||||
// Automatic cleanup to prevent goroutine leak when cache is garbage collected
|
||||
runtime.AddCleanup(cache, func(ttlCache *ttlcache.Cache[K, V]) {
|
||||
ttlCache.Stop()
|
||||
}, cache.data)
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
const evictionTimeout = 1 * time.Hour
|
||||
@@ -127,3 +139,15 @@ func (c *simpleCache[K, V]) Values() []V {
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *simpleCache[K, V]) Len() int {
|
||||
return c.data.Len()
|
||||
}
|
||||
|
||||
func (c *simpleCache[K, V]) OnExpiration(fn func(K, V)) func() {
|
||||
return c.data.OnEviction(func(_ context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[K, V]) {
|
||||
if reason == ttlcache.EvictionReasonExpired {
|
||||
fn(item.Key(), item.Value())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user