diff --git a/config.go b/config.go index 53f846f..9ad5b59 100644 --- a/config.go +++ b/config.go @@ -188,6 +188,10 @@ func (app *appContext) loadConfig() error { app.config.Section("jellyfin").Key("device").SetValue("jfa-go") app.config.Section("jellyfin").Key("device_id").SetValue(fmt.Sprintf("jfa-go-%s-%s", version, commit)) + app.MustSetValue("jellyfin", "cache_timeout", "30") + app.MustSetValue("jellyfin", "web_cache_async_timeout", "1") + app.MustSetValue("jellyfin", "web_cache_sync_timeout", "10") + LOGIP = app.config.Section("advanced").Key("log_ips").MustBool(false) LOGIPU = app.config.Section("advanced").Key("log_ips_users").MustBool(false) diff --git a/main.go b/main.go index edb863c..2ec8f7c 100644 --- a/main.go +++ b/main.go @@ -134,7 +134,7 @@ type appContext struct { pwrCaptchas map[string]Captcha ConfirmationKeys map[string]map[string]ConfirmationKey // Map of invite code to jwt to request confirmationKeysLock sync.Mutex - userCache UserCache + userCache *UserCache } func generateSecret(length int) (string, error) { @@ -406,7 +406,7 @@ func start(asDaemon, firstCall bool) { // Initialize jellyfin/emby connection server := app.config.Section("jellyfin").Key("server").String() - cacheTimeout := int(app.config.Section("jellyfin").Key("cache_timeout").MustUint(30)) + cacheTimeout := app.config.Section("jellyfin").Key("cache_timeout").MustInt() stringServerType := app.config.Section("jellyfin").Key("type").String() timeoutHandler := mediabrowser.NewNamedTimeoutHandler("Jellyfin", "\""+server+"\"", true) if stringServerType == "emby" { @@ -469,6 +469,11 @@ func start(asDaemon, firstCall bool) { } } + app.userCache = NewUserCache( + time.Minute*time.Duration(app.config.Section("jellyfin").Key("web_cache_async_timeout").MustInt()), + time.Minute*time.Duration(app.config.Section("jellyfin").Key("web_cache_sync_timeout").MustInt()), + ) + // Since email depends on language, the email reload in loadConfig won't work first time. // Email also handles its own proxying, as (SMTP atleast) doesn't use a HTTP transport. app.email = NewEmailer(app) diff --git a/usercache.go b/usercache.go index 194b7d2..5d52542 100644 --- a/usercache.go +++ b/usercache.go @@ -10,12 +10,8 @@ import ( ) const ( - // After cache is this old, re-sync, but do it in the background and return the old cache. - WEB_USER_CACHE_SYNC = 30 * time.Second - // After cache is this old, re-sync and wait for it and return the new cache. - WEB_USER_CACHE_WAIT_FOR_SYNC = 5 * time.Minute - USER_DEFAULT_SORT_FIELD = "name" - USER_DEFAULT_SORT_ASCENDING = true + USER_DEFAULT_SORT_FIELD = "name" + USER_DEFAULT_SORT_ASCENDING = true ) // UserCache caches the transport representation of users, @@ -28,19 +24,30 @@ type UserCache struct { Ref []*respUser Sorted bool LastSync time.Time - SyncLock sync.Mutex - Syncing bool - SortLock sync.Mutex - Sorting bool + // After cache is this old, re-sync, but do it in the background and return the old cache. + SyncTimeout time.Duration + // After cache is this old, re-sync and wait for it and return the new cache. + WaitForSyncTimeout time.Duration + SyncLock sync.Mutex + Syncing bool + SortLock sync.Mutex + Sorting bool +} + +func NewUserCache(syncTimeout, waitForSyncTimeout time.Duration) *UserCache { + return &UserCache{ + SyncTimeout: syncTimeout, + WaitForSyncTimeout: waitForSyncTimeout, + } } // MaybeSync (maybe) syncs the cache, resulting in updated UserCache.Cache/.Ref/.Sorted. -// Only syncs if WEB_USER_CACHE_SYNC duration has passed since last one. -// If WEB_USER_CACHE_WAIT_FOR_SYNC duration has passed, this will block until a sync is complete, otherwise it will sync in the background +// Only syncs if c.SyncTimeout duration has passed since last one. +// If c.WaitForSyncTimeout duration has passed, this will block until a sync is complete, otherwise it will sync in the background // (expecting you to use the old cache data). Only one sync will run at a time. func (c *UserCache) MaybeSync(app *appContext) error { - shouldWaitForSync := time.Now().After(c.LastSync.Add(WEB_USER_CACHE_WAIT_FOR_SYNC)) || c.Ref == nil || len(c.Ref) == 0 - shouldSync := time.Now().After(c.LastSync.Add(WEB_USER_CACHE_SYNC)) + shouldWaitForSync := time.Now().After(c.LastSync.Add(c.WaitForSyncTimeout)) || c.Ref == nil || len(c.Ref) == 0 + shouldSync := time.Now().After(c.LastSync.Add(c.SyncTimeout)) if !shouldSync { return nil