From fce1d5d7dce6a16429d0fe043555eac2c083ae7b Mon Sep 17 00:00:00 2001
From: wxiaoguang <wxiaoguang@gmail.com>
Date: Thu, 16 Nov 2023 20:53:42 +0800
Subject: [PATCH] Fix system config cache expiration timing (#28072)

To avoid unnecessary database access, the `cacheTime` should always be
set if the revision has been checked.

Fix #28057
---
 models/system/setting.go | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/models/system/setting.go b/models/system/setting.go
index 1ae6f5c652836..507d23cff6bbf 100644
--- a/models/system/setting.go
+++ b/models/system/setting.go
@@ -115,24 +115,26 @@ func (d *dbConfigCachedGetter) GetValue(ctx context.Context, key string) (v stri
 
 func (d *dbConfigCachedGetter) GetRevision(ctx context.Context) int {
 	d.mu.RLock()
-	defer d.mu.RUnlock()
-	if time.Since(d.cacheTime) < time.Second {
-		return d.revision
+	cachedDuration := time.Since(d.cacheTime)
+	cachedRevision := d.revision
+	d.mu.RUnlock()
+
+	if cachedDuration < time.Second {
+		return cachedRevision
 	}
+
+	d.mu.Lock()
+	defer d.mu.Unlock()
 	if GetRevision(ctx) != d.revision {
-		d.mu.RUnlock()
-		d.mu.Lock()
 		rev, set, err := GetAllSettings(ctx)
 		if err != nil {
 			log.Error("Unable to get all settings: %v", err)
 		} else {
-			d.cacheTime = time.Now()
 			d.revision = rev
 			d.settings = set
 		}
-		d.mu.Unlock()
-		d.mu.RLock()
 	}
+	d.cacheTime = time.Now()
 	return d.revision
 }