diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2022-11-10 14:43:53 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-10 14:43:53 +0800 |
commit | 385462d36c75e809ee082d3432941f938cbdffc9 (patch) | |
tree | 938946297d1c0fa736852e1054f732ed2b0db686 /models | |
parent | ce5aafbc698de72d8acf03851dc5db057b3cc01f (diff) | |
download | gitea-385462d36c75e809ee082d3432941f938cbdffc9.tar.gz gitea-385462d36c75e809ee082d3432941f938cbdffc9.zip |
Fix dashboard ignored system setting cache (#21621)
This is a performance regression from #18058
Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'models')
-rw-r--r-- | models/avatars/avatar.go | 11 | ||||
-rw-r--r-- | models/system/setting.go | 40 | ||||
-rw-r--r-- | models/system/setting_key.go | 5 | ||||
-rw-r--r-- | models/user/avatar.go | 6 | ||||
-rw-r--r-- | models/user/setting.go | 36 | ||||
-rw-r--r-- | models/user/setting_test.go | 2 |
6 files changed, 80 insertions, 20 deletions
diff --git a/models/avatars/avatar.go b/models/avatars/avatar.go index 418e9b9ccc..ec3b611312 100644 --- a/models/avatars/avatar.go +++ b/models/avatars/avatar.go @@ -150,10 +150,11 @@ func generateEmailAvatarLink(email string, size int, final bool) string { return DefaultAvatarLink() } - enableFederatedAvatar, _ := system_model.GetSetting(system_model.KeyPictureEnableFederatedAvatar) + enableFederatedAvatarSetting, _ := system_model.GetSetting(system_model.KeyPictureEnableFederatedAvatar) + enableFederatedAvatar := enableFederatedAvatarSetting.GetValueBool() var err error - if enableFederatedAvatar != nil && enableFederatedAvatar.GetValueBool() && system_model.LibravatarService != nil { + if enableFederatedAvatar && system_model.LibravatarService != nil { emailHash := saveEmailHash(email) if final { // for final link, we can spend more time on slow external query @@ -171,8 +172,10 @@ func generateEmailAvatarLink(email string, size int, final bool) string { return urlStr } - disableGravatar, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar) - if disableGravatar != nil && !disableGravatar.GetValueBool() { + disableGravatarSetting, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar) + + disableGravatar := disableGravatarSetting.GetValueBool() + if !disableGravatar { // copy GravatarSourceURL, because we will modify its Path. avatarURLCopy := *system_model.GravatarSourceURL avatarURLCopy.Path = path.Join(avatarURLCopy.Path, HashEmail(email)) diff --git a/models/system/setting.go b/models/system/setting.go index 9711d38f3b..b4011b1b3e 100644 --- a/models/system/setting.go +++ b/models/system/setting.go @@ -12,6 +12,7 @@ import ( "strings" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" @@ -35,6 +36,10 @@ func (s *Setting) TableName() string { } func (s *Setting) GetValueBool() bool { + if s == nil { + return false + } + b, _ := strconv.ParseBool(s.SettingValue) return b } @@ -75,8 +80,8 @@ func IsErrDataExpired(err error) bool { return ok } -// GetSetting returns specific setting -func GetSetting(key string) (*Setting, error) { +// GetSettingNoCache returns specific setting without using the cache +func GetSettingNoCache(key string) (*Setting, error) { v, err := GetSettings([]string{key}) if err != nil { return nil, err @@ -87,6 +92,24 @@ func GetSetting(key string) (*Setting, error) { return v[key], nil } +// GetSetting returns the setting value via the key +func GetSetting(key string) (*Setting, error) { + return cache.Get(genSettingCacheKey(key), func() (*Setting, error) { + res, err := GetSettingNoCache(key) + if err != nil { + return nil, err + } + return res, nil + }) +} + +// GetSettingBool return bool value of setting, +// none existing keys and errors are ignored and result in false +func GetSettingBool(key string) bool { + s, _ := GetSetting(key) + return s.GetValueBool() +} + // GetSettings returns specific settings func GetSettings(keys []string) (map[string]*Setting, error) { for i := 0; i < len(keys); i++ { @@ -139,12 +162,13 @@ func GetAllSettings() (AllSettings, error) { // DeleteSetting deletes a specific setting for a user func DeleteSetting(setting *Setting) error { + cache.Remove(genSettingCacheKey(setting.SettingKey)) _, err := db.GetEngine(db.DefaultContext).Delete(setting) return err } func SetSettingNoVersion(key, value string) error { - s, err := GetSetting(key) + s, err := GetSettingNoCache(key) if IsErrSettingIsNotExist(err) { return SetSetting(&Setting{ SettingKey: key, @@ -160,9 +184,13 @@ func SetSettingNoVersion(key, value string) error { // SetSetting updates a users' setting for a specific key func SetSetting(setting *Setting) error { - if err := upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version); err != nil { + _, err := cache.Set(genSettingCacheKey(setting.SettingKey), func() (*Setting, error) { + return setting, upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version) + }) + if err != nil { return err } + setting.Version++ return nil } @@ -213,7 +241,7 @@ var ( func Init() error { var disableGravatar bool - disableGravatarSetting, err := GetSetting(KeyPictureDisableGravatar) + disableGravatarSetting, err := GetSettingNoCache(KeyPictureDisableGravatar) if IsErrSettingIsNotExist(err) { disableGravatar = setting.GetDefaultDisableGravatar() disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)} @@ -224,7 +252,7 @@ func Init() error { } var enableFederatedAvatar bool - enableFederatedAvatarSetting, err := GetSetting(KeyPictureEnableFederatedAvatar) + enableFederatedAvatarSetting, err := GetSettingNoCache(KeyPictureEnableFederatedAvatar) if IsErrSettingIsNotExist(err) { enableFederatedAvatar = setting.GetDefaultEnableFederatedAvatar(disableGravatar) enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)} diff --git a/models/system/setting_key.go b/models/system/setting_key.go index 5a6ea6ed72..14105b89d0 100644 --- a/models/system/setting_key.go +++ b/models/system/setting_key.go @@ -9,3 +9,8 @@ const ( KeyPictureDisableGravatar = "picture.disable_gravatar" KeyPictureEnableFederatedAvatar = "picture.enable_federated_avatar" ) + +// genSettingCacheKey returns the cache key for some configuration +func genSettingCacheKey(key string) string { + return "system.setting." + key +} diff --git a/models/user/avatar.go b/models/user/avatar.go index f73ac56c5e..102206f3a2 100644 --- a/models/user/avatar.go +++ b/models/user/avatar.go @@ -68,11 +68,9 @@ func (u *User) AvatarLinkWithSize(size int) string { useLocalAvatar := false autoGenerateAvatar := false - var disableGravatar bool disableGravatarSetting, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar) - if disableGravatarSetting != nil { - disableGravatar = disableGravatarSetting.GetValueBool() - } + + disableGravatar := disableGravatarSetting.GetValueBool() switch { case u.UseCustomAvatar: diff --git a/models/user/setting.go b/models/user/setting.go index 5fe7c2ec23..896f3c8da1 100644 --- a/models/user/setting.go +++ b/models/user/setting.go @@ -10,6 +10,7 @@ import ( "strings" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/cache" "xorm.io/builder" ) @@ -47,9 +48,25 @@ func IsErrUserSettingIsNotExist(err error) bool { return ok } -// GetSetting returns specific setting +// genSettingCacheKey returns the cache key for some configuration +func genSettingCacheKey(userID int64, key string) string { + return fmt.Sprintf("user_%d.setting.%s", userID, key) +} + +// GetSetting returns the setting value via the key func GetSetting(uid int64, key string) (*Setting, error) { - v, err := GetUserSettings(uid, []string{key}) + return cache.Get(genSettingCacheKey(uid, key), func() (*Setting, error) { + res, err := GetSettingNoCache(uid, key) + if err != nil { + return nil, err + } + return res, nil + }) +} + +// GetSettingNoCache returns specific setting without using the cache +func GetSettingNoCache(uid int64, key string) (*Setting, error) { + v, err := GetSettings(uid, []string{key}) if err != nil { return nil, err } @@ -59,8 +76,8 @@ func GetSetting(uid int64, key string) (*Setting, error) { return v[key], nil } -// GetUserSettings returns specific settings from user -func GetUserSettings(uid int64, keys []string) (map[string]*Setting, error) { +// GetSettings returns specific settings from user +func GetSettings(uid int64, keys []string) (map[string]*Setting, error) { settings := make([]*Setting, 0, len(keys)) if err := db.GetEngine(db.DefaultContext). Where("user_id=?", uid). @@ -105,6 +122,7 @@ func GetUserSetting(userID int64, key string, def ...string) (string, error) { if err := validateUserSettingKey(key); err != nil { return "", err } + setting := &Setting{UserID: userID, SettingKey: key} has, err := db.GetEngine(db.DefaultContext).Get(setting) if err != nil { @@ -124,7 +142,10 @@ func DeleteUserSetting(userID int64, key string) error { if err := validateUserSettingKey(key); err != nil { return err } + + cache.Remove(genSettingCacheKey(userID, key)) _, err := db.GetEngine(db.DefaultContext).Delete(&Setting{UserID: userID, SettingKey: key}) + return err } @@ -133,7 +154,12 @@ func SetUserSetting(userID int64, key, value string) error { if err := validateUserSettingKey(key); err != nil { return err } - return upsertUserSettingValue(userID, key, value) + + _, err := cache.Set(genSettingCacheKey(userID, key), func() (string, error) { + return value, upsertUserSettingValue(userID, key, value) + }) + + return err } func upsertUserSettingValue(userID int64, key, value string) error { diff --git a/models/user/setting_test.go b/models/user/setting_test.go index f0083038df..5a772a8ce7 100644 --- a/models/user/setting_test.go +++ b/models/user/setting_test.go @@ -27,7 +27,7 @@ func TestSettings(t *testing.T) { assert.NoError(t, err) // get specific setting - settings, err := user_model.GetUserSettings(99, []string{keyName}) + settings, err := user_model.GetSettings(99, []string{keyName}) assert.NoError(t, err) assert.Len(t, settings, 1) assert.EqualValues(t, newSetting.SettingValue, settings[keyName].SettingValue) |