mirror of
https://github.com/navidrome/navidrome.git
synced 2026-08-31 07:30:32 +00:00
refactor(config): make the artwork tuning options dev flags
ArtworkWorkerConcurrency and ArtworkExternalMaxRPS become DevArtworkWorkerConcurrency and DevArtworkExternalMaxRPS, joining the other DevArtwork* flags. Their defaults should not need tuning, so they do not belong in the documented, user-facing option set.
This commit is contained in:
parent
fbcda30473
commit
34f6684922
@ -62,8 +62,6 @@ type configOptions struct {
|
||||
ImageCacheSize string
|
||||
AlbumPlayCountMode string
|
||||
EnableArtworkPrecache bool
|
||||
ArtworkWorkerConcurrency int
|
||||
ArtworkExternalMaxRPS int
|
||||
AutoImportPlaylists bool
|
||||
DefaultPlaylistPublicVisibility bool
|
||||
PlaylistsPath string
|
||||
@ -146,6 +144,8 @@ type configOptions struct {
|
||||
DevArtworkThrottleBacklogLimit int
|
||||
DevArtworkThrottleBacklogTimeout time.Duration
|
||||
DevArtworkThrottleBuffered bool
|
||||
DevArtworkWorkerConcurrency int
|
||||
DevArtworkExternalMaxRPS int
|
||||
DevArtistInfoTimeToLive time.Duration
|
||||
DevAlbumInfoTimeToLive time.Duration
|
||||
DevExternalScanner bool
|
||||
@ -1075,10 +1075,10 @@ func setViperDefaults() {
|
||||
viper.SetDefault("devartworkthrottlebuffered", true)
|
||||
// Half the CPU count (min 2), so local resolution scales with the host but stays under the
|
||||
// SQLite pool (MaxOpenConns) — leaving connections for the scanner, scrobbles and the UI.
|
||||
viper.SetDefault("artworkworkerconcurrency", max(2, runtime.NumCPU()/2))
|
||||
viper.SetDefault("devartworkworkerconcurrency", max(2, runtime.NumCPU()/2))
|
||||
// External RPS gates outbound calls to third-party services (per service); it is bounded by
|
||||
// their tolerance, not the host, so it stays a small constant regardless of CPU count.
|
||||
viper.SetDefault("artworkexternalmaxrps", 2)
|
||||
viper.SetDefault("devartworkexternalmaxrps", 2)
|
||||
viper.SetDefault("devartistinfotimetolive", consts.ArtistInfoTimeToLive)
|
||||
viper.SetDefault("devalbuminfotimetolive", consts.AlbumInfoTimeToLive)
|
||||
viper.SetDefault("devexternalscanner", true)
|
||||
|
||||
@ -65,7 +65,7 @@ var _ = Describe("Acquisition → serve loop", func() {
|
||||
conf.Server.CoverArtPriority = "cover.jpg"
|
||||
conf.Server.ArtistArtPriority = "artist.png" // keeps artist resolution offline
|
||||
conf.Server.EnableMediaFileCoverArt = true
|
||||
conf.Server.ArtworkWorkerConcurrency = 1
|
||||
conf.Server.DevArtworkWorkerConcurrency = 1
|
||||
|
||||
folderRepo = &fakeFolderRepo{}
|
||||
libRepo = &tests.MockLibraryRepo{}
|
||||
|
||||
@ -90,7 +90,7 @@ func setupResolutionHarness() {
|
||||
conf.Server.ImageCacheSize = "0"
|
||||
conf.Server.EnableExternalServices = false
|
||||
conf.Server.EnableMediaFileCoverArt = true
|
||||
conf.Server.ArtworkWorkerConcurrency = 1
|
||||
conf.Server.DevArtworkWorkerConcurrency = 1
|
||||
|
||||
rctx = request.WithUser(GinkgoT().Context(), model.User{ID: "admin-1", UserName: "admin", IsAdmin: true})
|
||||
harness.TruncateDB(userTables)
|
||||
|
||||
@ -67,7 +67,7 @@ func (w *Worker) gateFor(name string) *extGate {
|
||||
if g, ok := w.gates[name]; ok {
|
||||
return g
|
||||
}
|
||||
rps := conf.Server.ArtworkExternalMaxRPS
|
||||
rps := conf.Server.DevArtworkExternalMaxRPS
|
||||
limit := rate.Inf
|
||||
if rps > 0 {
|
||||
limit = rate.Limit(rps)
|
||||
|
||||
@ -71,9 +71,9 @@ func NewWorker(ds model.DataStore, store *ImageStore, ag *agents.Agents, ffmpeg
|
||||
// rate-limit permit, so a sleeping lookup would crowd out a cover sitting on disk.
|
||||
func newDrainPools() []*drainPool {
|
||||
budget := conf.MaxOpenConns() // floored at 4, so both remainders below stay positive
|
||||
local := min(max(1, conf.Server.ArtworkWorkerConcurrency), budget-1)
|
||||
local := min(max(1, conf.Server.DevArtworkWorkerConcurrency), budget-1)
|
||||
// More external slots than the rate allows would only sleep in the limiter.
|
||||
external := min(max(2, 2*conf.Server.ArtworkExternalMaxRPS), budget-local)
|
||||
external := min(max(2, 2*conf.Server.DevArtworkExternalMaxRPS), budget-local)
|
||||
return []*drainPool{
|
||||
{name: "local", kinds: localDrainKinds, concurrency: local, wake: make(chan struct{}, 1)},
|
||||
{name: "external", kinds: externalDrainKinds, concurrency: external, wake: make(chan struct{}, 1)},
|
||||
|
||||
@ -145,7 +145,7 @@ var _ = Describe("Worker", func() {
|
||||
ds.MockedAlbum = tests.CreateMockAlbumRepo()
|
||||
store = NewImageStore(GinkgoT().TempDir())
|
||||
conf.Server.CoverArtPriority = "cover.jpg, embedded"
|
||||
conf.Server.ArtworkExternalMaxRPS = 1000 // keep the limiter out of the way of behavior tests
|
||||
conf.Server.DevArtworkExternalMaxRPS = 1000 // keep the limiter out of the way of behavior tests
|
||||
broker = &fakeEventBroker{}
|
||||
imgCache = &recordingCache{FileCache: cache.NewFileCache("WorkerTest", "100MB", "images", 0,
|
||||
func(ctx context.Context, arg cache.Item) (io.Reader, error) {
|
||||
|
||||
@ -93,7 +93,7 @@ var _ = Describe("Artwork Serving", Ordered, func() {
|
||||
conf.Server.CoverArtPriority = "cover.jpg"
|
||||
conf.Server.ArtistArtPriority = "artist.png" // offline: artists resolve absent, out of scope here
|
||||
conf.Server.EnableMediaFileCoverArt = false
|
||||
conf.Server.ArtworkWorkerConcurrency = 1
|
||||
conf.Server.DevArtworkWorkerConcurrency = 1
|
||||
conf.Server.CacheFolder = conf.NewDir(GinkgoT().TempDir())
|
||||
conf.Server.EnableSharing = true
|
||||
conf.Server.DevArtworkMaxRequests = 100
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user