keep only 3 most recently used proxy URLs active

This commit is contained in:
Drew Weymouth
2025-03-29 15:15:13 -07:00
parent d4c1b560d5
commit e4c187b4df
+57 -17
View File
@@ -33,6 +33,11 @@ const (
var unimplemented = errors.New("unimplemented") var unimplemented = errors.New("unimplemented")
type proxyMapEntry struct {
key string
url string
}
type DLNAPlayer struct { type DLNAPlayer struct {
player.BasePlayerCallbackImpl player.BasePlayerCallbackImpl
@@ -54,8 +59,12 @@ type DLNAPlayer struct {
localIP string localIP string
proxyPort int proxyPort int
// keep in order of most recently accessed at the end
// that way the item in proxyURLs[0] can be kicked out
// when adding a new URL to the proxy, since
// only two will need to be active at any given time
proxyURLs [3]proxyMapEntry
proxyURLLock sync.Mutex proxyURLLock sync.Mutex
proxyURLs map[string]string
timerActive atomic.Bool timerActive atomic.Bool
timer *time.Timer timer *time.Timer
@@ -82,7 +91,6 @@ func NewDLNAPlayer(device *device.MediaRenderer) (*DLNAPlayer, error) {
return &DLNAPlayer{ return &DLNAPlayer{
avTransport: avt, avTransport: avt,
renderControl: rc, renderControl: rc,
proxyURLs: make(map[string]string),
resetChan: make(chan time.Duration), resetChan: make(chan time.Duration),
}, nil }, nil
} }
@@ -256,15 +264,6 @@ func (d *DLNAPlayer) ensureSetupProxy() error {
return nil return nil
} }
func (d *DLNAPlayer) addURLToProxy(url string) string {
hash := md5.Sum([]byte(url))
key := base64.StdEncoding.EncodeToString(hash[:])
d.proxyURLLock.Lock()
d.proxyURLs[key] = url
d.proxyURLLock.Unlock()
return key
}
func (d *DLNAPlayer) setTrackChangeTimer(dur time.Duration) { func (d *DLNAPlayer) setTrackChangeTimer(dur time.Duration) {
if d.timerActive.Swap(true) { if d.timerActive.Swap(true) {
// was active // was active
@@ -339,13 +338,8 @@ func (d *DLNAPlayer) urlForItem(key string) string {
} }
func (d *DLNAPlayer) handleRequest(w http.ResponseWriter, r *http.Request) { func (d *DLNAPlayer) handleRequest(w http.ResponseWriter, r *http.Request) {
var url string
key := strings.TrimPrefix(r.URL.Path, "/") key := strings.TrimPrefix(r.URL.Path, "/")
d.proxyURLLock.Lock() url, _ := d.lookupProxyURL(key)
if u, ok := d.proxyURLs[key]; ok {
url = u
}
d.proxyURLLock.Unlock()
if url == "" { if url == "" {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
@@ -389,6 +383,52 @@ func (d *DLNAPlayer) handleRequest(w http.ResponseWriter, r *http.Request) {
} }
} }
func (d *DLNAPlayer) addURLToProxy(url string) string {
hash := md5.Sum([]byte(url))
key := base64.StdEncoding.EncodeToString(hash[:])
d.proxyURLLock.Lock()
defer d.proxyURLLock.Unlock()
d._updateProxyURL(key, url)
return key
}
// lookupProxyURL finds a URL by key and updates its position to most recently used
func (d *DLNAPlayer) lookupProxyURL(key string) (string, bool) {
d.proxyURLLock.Lock()
defer d.proxyURLLock.Unlock()
for i := 0; i < len(d.proxyURLs); i++ {
if d.proxyURLs[i].key == key {
url := d.proxyURLs[i].url
// Move accessed entry to the most recent position
d._updateProxyURL(key, url)
return url, true
}
}
return "", false
}
func (d *DLNAPlayer) _updateProxyURL(key, url string) {
// Check if the key already exists, and if so, move it to the most recently used position
for i := 0; i < len(d.proxyURLs); i++ {
if d.proxyURLs[i].key == key {
if i < len(d.proxyURLs)-1 {
// Shift elements to the left from found position to the end
copy(d.proxyURLs[i:], d.proxyURLs[i+1:])
}
// Place updated entry at the last position
d.proxyURLs[len(d.proxyURLs)-1] = proxyMapEntry{key: key, url: url}
return
}
}
// Shift all elements left to make room for the new entry at the end
copy(d.proxyURLs[:], d.proxyURLs[1:])
// Insert new element at the most recent position
d.proxyURLs[len(d.proxyURLs)-1] = proxyMapEntry{key: key, url: url}
}
type retryLogger struct{} type retryLogger struct{}
func (retryLogger) Error(msg string, keysAndValues ...interface{}) { func (retryLogger) Error(msg string, keysAndValues ...interface{}) {