Jelajahi Sumber

chore: add MEMORY_CACHE_ENABLED env variable

JustSong 2 tahun lalu
induk
melakukan
f9b748c2ca
5 mengubah file dengan 25 tambahan dan 22 penghapusan
  1. 11 9
      README.md
  2. 2 1
      common/constants.go
  3. 10 10
      main.go
  4. 1 1
      middleware/auth.go
  5. 1 1
      model/cache.go

+ 11 - 9
README.md

@@ -309,22 +309,24 @@ graph LR
      + `SQL_CONN_MAX_LIFETIME`:连接的最大生命周期,默认为 `60`,单位分钟。
      + `SQL_CONN_MAX_LIFETIME`:连接的最大生命周期,默认为 `60`,单位分钟。
 4. `FRONTEND_BASE_URL`:设置之后将重定向页面请求到指定的地址,仅限从服务器设置。
 4. `FRONTEND_BASE_URL`:设置之后将重定向页面请求到指定的地址,仅限从服务器设置。
    + 例子:`FRONTEND_BASE_URL=https://openai.justsong.cn`
    + 例子:`FRONTEND_BASE_URL=https://openai.justsong.cn`
-5. `SYNC_FREQUENCY`:设置之后将定期与数据库同步配置,单位为秒,未设置则不进行同步。
+5. `MEMORY_CACHE_ENABLED`:启用内存缓存,会导致用户额度的更新存在一定的延迟,可选值为 `true` 和 `false`,未设置则默认为 `false`。
+   + 例子:`MEMORY_CACHE_ENABLED=true`
+6. `SYNC_FREQUENCY`:在启用缓存的情况下与数据库同步配置的频率,单位为秒,默认为 `600` 秒。
    + 例子:`SYNC_FREQUENCY=60`
    + 例子:`SYNC_FREQUENCY=60`
-6. `NODE_TYPE`:设置之后将指定节点类型,可选值为 `master` 和 `slave`,未设置则默认为 `master`。
+7. `NODE_TYPE`:设置之后将指定节点类型,可选值为 `master` 和 `slave`,未设置则默认为 `master`。
    + 例子:`NODE_TYPE=slave`
    + 例子:`NODE_TYPE=slave`
-7. `CHANNEL_UPDATE_FREQUENCY`:设置之后将定期更新渠道余额,单位为分钟,未设置则不进行更新。
+8. `CHANNEL_UPDATE_FREQUENCY`:设置之后将定期更新渠道余额,单位为分钟,未设置则不进行更新。
    + 例子:`CHANNEL_UPDATE_FREQUENCY=1440`
    + 例子:`CHANNEL_UPDATE_FREQUENCY=1440`
-8. `CHANNEL_TEST_FREQUENCY`:设置之后将定期检查渠道,单位为分钟,未设置则不进行检查。
+9. `CHANNEL_TEST_FREQUENCY`:设置之后将定期检查渠道,单位为分钟,未设置则不进行检查。
    + 例子:`CHANNEL_TEST_FREQUENCY=1440`
    + 例子:`CHANNEL_TEST_FREQUENCY=1440`
-9. `POLLING_INTERVAL`:批量更新渠道余额以及测试可用性时的请求间隔,单位为秒,默认无间隔。
-   + 例子:`POLLING_INTERVAL=5`
-10. `BATCH_UPDATE_ENABLED`:启用数据库批量更新聚合,会导致用户额度的更新存在一定的延迟可选值为 `true` 和 `false`,未设置则默认为 `false`。
+10. `POLLING_INTERVAL`:批量更新渠道余额以及测试可用性时的请求间隔,单位为秒,默认无间隔。
+    + 例子:`POLLING_INTERVAL=5`
+11. `BATCH_UPDATE_ENABLED`:启用数据库批量更新聚合,会导致用户额度的更新存在一定的延迟可选值为 `true` 和 `false`,未设置则默认为 `false`。
     + 例子:`BATCH_UPDATE_ENABLED=true`
     + 例子:`BATCH_UPDATE_ENABLED=true`
     + 如果你遇到了数据库连接数过多的问题,可以尝试启用该选项。
     + 如果你遇到了数据库连接数过多的问题,可以尝试启用该选项。
-11. `BATCH_UPDATE_INTERVAL=5`:批量更新聚合的时间间隔,单位为秒,默认为 `5`。
+12. `BATCH_UPDATE_INTERVAL=5`:批量更新聚合的时间间隔,单位为秒,默认为 `5`。
     + 例子:`BATCH_UPDATE_INTERVAL=5`
     + 例子:`BATCH_UPDATE_INTERVAL=5`
-12. 请求频率限制:
+13. 请求频率限制:
     + `GLOBAL_API_RATE_LIMIT`:全局 API 速率限制(除中继请求外),单 ip 三分钟内的最大请求数,默认为 `180`。
     + `GLOBAL_API_RATE_LIMIT`:全局 API 速率限制(除中继请求外),单 ip 三分钟内的最大请求数,默认为 `180`。
     + `GLOBAL_WEB_RATE_LIMIT`:全局 Web 速率限制,单 ip 三分钟内的最大请求数,默认为 `60`。
     + `GLOBAL_WEB_RATE_LIMIT`:全局 Web 速率限制,单 ip 三分钟内的最大请求数,默认为 `60`。
 
 

+ 2 - 1
common/constants.go

@@ -56,6 +56,7 @@ var EmailDomainWhitelist = []string{
 }
 }
 
 
 var DebugEnabled = os.Getenv("DEBUG") == "true"
 var DebugEnabled = os.Getenv("DEBUG") == "true"
+var MemoryCacheEnabled = os.Getenv("MEMORY_CACHE_ENABLED") == "true"
 
 
 var LogConsumeEnabled = true
 var LogConsumeEnabled = true
 
 
@@ -92,7 +93,7 @@ var IsMasterNode = os.Getenv("NODE_TYPE") != "slave"
 var requestInterval, _ = strconv.Atoi(os.Getenv("POLLING_INTERVAL"))
 var requestInterval, _ = strconv.Atoi(os.Getenv("POLLING_INTERVAL"))
 var RequestInterval = time.Duration(requestInterval) * time.Second
 var RequestInterval = time.Duration(requestInterval) * time.Second
 
 
-var SyncFrequency = 10 * 60 // unit is second, will be overwritten by SYNC_FREQUENCY
+var SyncFrequency = GetOrDefault("SYNC_FREQUENCY", 10*60) // unit is second
 
 
 var BatchUpdateEnabled = false
 var BatchUpdateEnabled = false
 var BatchUpdateInterval = GetOrDefault("BATCH_UPDATE_INTERVAL", 5)
 var BatchUpdateInterval = GetOrDefault("BATCH_UPDATE_INTERVAL", 5)

+ 10 - 10
main.go

@@ -2,6 +2,7 @@ package main
 
 
 import (
 import (
 	"embed"
 	"embed"
+	"fmt"
 	"github.com/gin-contrib/sessions"
 	"github.com/gin-contrib/sessions"
 	"github.com/gin-contrib/sessions/cookie"
 	"github.com/gin-contrib/sessions/cookie"
 	"github.com/gin-gonic/gin"
 	"github.com/gin-gonic/gin"
@@ -50,18 +51,17 @@ func main() {
 	// Initialize options
 	// Initialize options
 	model.InitOptionMap()
 	model.InitOptionMap()
 	if common.RedisEnabled {
 	if common.RedisEnabled {
+		// for compatibility with old versions
+		common.MemoryCacheEnabled = true
+	}
+	if common.MemoryCacheEnabled {
+		common.SysLog("memory cache enabled")
+		common.SysError(fmt.Sprintf("sync frequency: %d seconds", common.SyncFrequency))
 		model.InitChannelCache()
 		model.InitChannelCache()
 	}
 	}
-	if os.Getenv("SYNC_FREQUENCY") != "" {
-		frequency, err := strconv.Atoi(os.Getenv("SYNC_FREQUENCY"))
-		if err != nil {
-			common.FatalLog("failed to parse SYNC_FREQUENCY: " + err.Error())
-		}
-		common.SyncFrequency = frequency
-		go model.SyncOptions(frequency)
-		if common.RedisEnabled {
-			go model.SyncChannelCache(frequency)
-		}
+	if common.MemoryCacheEnabled {
+		go model.SyncOptions(common.SyncFrequency)
+		go model.SyncChannelCache(common.SyncFrequency)
 	}
 	}
 	if os.Getenv("CHANNEL_UPDATE_FREQUENCY") != "" {
 	if os.Getenv("CHANNEL_UPDATE_FREQUENCY") != "" {
 		frequency, err := strconv.Atoi(os.Getenv("CHANNEL_UPDATE_FREQUENCY"))
 		frequency, err := strconv.Atoi(os.Getenv("CHANNEL_UPDATE_FREQUENCY"))

+ 1 - 1
middleware/auth.go

@@ -94,7 +94,7 @@ func TokenAuth() func(c *gin.Context) {
 			abortWithMessage(c, http.StatusUnauthorized, err.Error())
 			abortWithMessage(c, http.StatusUnauthorized, err.Error())
 			return
 			return
 		}
 		}
-		userEnabled, err := model.IsUserEnabled(token.UserId)
+		userEnabled, err := model.CacheIsUserEnabled(token.UserId)
 		if err != nil {
 		if err != nil {
 			abortWithMessage(c, http.StatusInternalServerError, err.Error())
 			abortWithMessage(c, http.StatusInternalServerError, err.Error())
 			return
 			return

+ 1 - 1
model/cache.go

@@ -186,7 +186,7 @@ func SyncChannelCache(frequency int) {
 }
 }
 
 
 func CacheGetRandomSatisfiedChannel(group string, model string) (*Channel, error) {
 func CacheGetRandomSatisfiedChannel(group string, model string) (*Channel, error) {
-	if !common.RedisEnabled {
+	if !common.MemoryCacheEnabled {
 		return GetRandomSatisfiedChannel(group, model)
 		return GetRandomSatisfiedChannel(group, model)
 	}
 	}
 	channelSyncLock.RLock()
 	channelSyncLock.RLock()