mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-14 21:37:09 +02:00
fix(jellyfin): memoize stable server Id and cover get-or-create path
This commit is contained in:
parent
910c239e29
commit
73376f519d
3 changed files with 48 additions and 10 deletions
|
|
@ -3,6 +3,7 @@ package jellyfin
|
|||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/navidrome/navidrome/core"
|
||||
|
|
@ -23,6 +24,8 @@ type Router struct {
|
|||
players core.Players
|
||||
scrobbler scrobbler.PlayTracker
|
||||
playlists playlists.Playlists
|
||||
serverIDOnce sync.Once
|
||||
serverIDVal string
|
||||
}
|
||||
|
||||
func New(ds model.DataStore, artwork artwork.Artwork, streamer stream.MediaStreamer,
|
||||
|
|
|
|||
|
|
@ -22,18 +22,25 @@ func (api *Router) serverName() string {
|
|||
// the same way core/metrics/insights.go derives its InsightsID. Jellyfin clients cache
|
||||
// ServerId across sessions, so a per-process value would break re-authentication.
|
||||
// api.ds is nil only in unit tests that construct Router{} directly; New() always sets it.
|
||||
//
|
||||
// Resolution happens once per Router (sync.Once), so concurrent first-boot requests can't
|
||||
// each generate and persist a different UUID before the row settles.
|
||||
func (api *Router) serverID(ctx context.Context) string {
|
||||
if api.ds == nil {
|
||||
return uuid.NewString()
|
||||
}
|
||||
id, err := api.ds.Property(ctx).Get(consts.JellyfinServerIDKey)
|
||||
if err != nil {
|
||||
id = uuid.NewString()
|
||||
if err := api.ds.Property(ctx).Put(consts.JellyfinServerIDKey, id); err != nil {
|
||||
log.Error(ctx, "Jellyfin API: could not persist server id", err)
|
||||
api.serverIDOnce.Do(func() {
|
||||
if api.ds == nil {
|
||||
api.serverIDVal = uuid.NewString()
|
||||
return
|
||||
}
|
||||
}
|
||||
return id
|
||||
id, err := api.ds.Property(ctx).Get(consts.JellyfinServerIDKey)
|
||||
if err != nil {
|
||||
id = uuid.NewString()
|
||||
if err := api.ds.Property(ctx).Put(consts.JellyfinServerIDKey, id); err != nil {
|
||||
log.Error(ctx, "Jellyfin API: could not persist server id", err)
|
||||
}
|
||||
}
|
||||
api.serverIDVal = id
|
||||
})
|
||||
return api.serverIDVal
|
||||
}
|
||||
|
||||
func (api *Router) publicInfo(ctx context.Context) dto.PublicSystemInfo {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package jellyfin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
"github.com/navidrome/navidrome/server/jellyfin/dto"
|
||||
"github.com/navidrome/navidrome/tests"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
|
@ -49,4 +51,30 @@ var _ = Describe("System", func() {
|
|||
Expect(json.Unmarshal(w.Body.Bytes(), &enabled)).To(Succeed())
|
||||
Expect(enabled).To(BeFalse())
|
||||
})
|
||||
|
||||
Context("serverID with a real DataStore", func() {
|
||||
var ctx context.Context
|
||||
var ds *tests.MockDataStore
|
||||
|
||||
BeforeEach(func() {
|
||||
ctx = context.Background()
|
||||
ds = &tests.MockDataStore{}
|
||||
})
|
||||
|
||||
It("persists the generated id so it can be read back by another Router sharing the same DataStore", func() {
|
||||
first := &Router{ds: ds}
|
||||
id := first.serverID(ctx)
|
||||
Expect(id).ToNot(BeEmpty())
|
||||
|
||||
second := &Router{ds: ds}
|
||||
Expect(second.serverID(ctx)).To(Equal(id))
|
||||
})
|
||||
|
||||
It("memoizes the id across repeated calls on the same Router", func() {
|
||||
r := &Router{ds: ds}
|
||||
id := r.serverID(ctx)
|
||||
Expect(r.serverID(ctx)).To(Equal(id))
|
||||
Expect(r.serverID(ctx)).To(Equal(id))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue