fix: when cached quota is too low, force refresh it

This commit is contained in:
JustSong 2024-03-13 19:38:44 +08:00
parent 0710f8cd66
commit a72e5fcc9e
5 changed files with 21 additions and 15 deletions

View File

@ -1,6 +1,7 @@
package model package model
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -70,38 +71,42 @@ func CacheGetUserGroup(id int) (group string, err error) {
return group, err return group, err
} }
func fetchAndUpdateUserQuota(id int) (quota int, err error) { func fetchAndUpdateUserQuota(ctx context.Context, id int) (quota int, err error) {
quota, err = GetUserQuota(id) quota, err = GetUserQuota(id)
if err != nil { if err != nil {
return 0, err return 0, err
} }
err = common.RedisSet(fmt.Sprintf("user_quota:%d", id), fmt.Sprintf("%d", quota), time.Duration(UserId2QuotaCacheSeconds)*time.Second) err = common.RedisSet(fmt.Sprintf("user_quota:%d", id), fmt.Sprintf("%d", quota), time.Duration(UserId2QuotaCacheSeconds)*time.Second)
if err != nil { if err != nil {
logger.SysError("Redis set user quota error: " + err.Error()) logger.Error(ctx, "Redis set user quota error: "+err.Error())
} }
return return
} }
func CacheGetUserQuota(id int) (quota int, err error) { func CacheGetUserQuota(ctx context.Context, id int) (quota int, err error) {
if !common.RedisEnabled { if !common.RedisEnabled {
return GetUserQuota(id) return GetUserQuota(id)
} }
quotaString, err := common.RedisGet(fmt.Sprintf("user_quota:%d", id)) quotaString, err := common.RedisGet(fmt.Sprintf("user_quota:%d", id))
if err != nil { if err != nil {
return fetchAndUpdateUserQuota(id) return fetchAndUpdateUserQuota(ctx, id)
} }
quota, err = strconv.Atoi(quotaString) quota, err = strconv.Atoi(quotaString)
if quota <= config.PreConsumedQuota { // when user's quota is less than pre-consumed quota, we need to fetch from db if err != nil {
return fetchAndUpdateUserQuota(id) return 0, nil
} }
return quota, err if quota <= config.PreConsumedQuota { // when user's quota is less than pre-consumed quota, we need to fetch from db
logger.Infof(ctx, "user %d's cached quota is too low: %d, refreshing from db", quota, id)
return fetchAndUpdateUserQuota(ctx, id)
}
return quota, nil
} }
func CacheUpdateUserQuota(id int) error { func CacheUpdateUserQuota(ctx context.Context, id int) error {
if !common.RedisEnabled { if !common.RedisEnabled {
return nil return nil
} }
quota, err := CacheGetUserQuota(id) quota, err := CacheGetUserQuota(ctx, id)
if err != nil { if err != nil {
return err return err
} }

View File

@ -22,6 +22,7 @@ import (
) )
func RelayAudioHelper(c *gin.Context, relayMode int) *relaymodel.ErrorWithStatusCode { func RelayAudioHelper(c *gin.Context, relayMode int) *relaymodel.ErrorWithStatusCode {
ctx := c.Request.Context()
audioModel := "whisper-1" audioModel := "whisper-1"
tokenId := c.GetInt("token_id") tokenId := c.GetInt("token_id")
@ -58,7 +59,7 @@ func RelayAudioHelper(c *gin.Context, relayMode int) *relaymodel.ErrorWithStatus
default: default:
preConsumedQuota = int(float64(config.PreConsumedQuota) * ratio) preConsumedQuota = int(float64(config.PreConsumedQuota) * ratio)
} }
userQuota, err := model.CacheGetUserQuota(userId) userQuota, err := model.CacheGetUserQuota(ctx, userId)
if err != nil { if err != nil {
return openai.ErrorWrapper(err, "get_user_quota_failed", http.StatusInternalServerError) return openai.ErrorWrapper(err, "get_user_quota_failed", http.StatusInternalServerError)
} }

View File

@ -118,7 +118,7 @@ func getPreConsumedQuota(textRequest *relaymodel.GeneralOpenAIRequest, promptTok
func preConsumeQuota(ctx context.Context, textRequest *relaymodel.GeneralOpenAIRequest, promptTokens int, ratio float64, meta *util.RelayMeta) (int, *relaymodel.ErrorWithStatusCode) { func preConsumeQuota(ctx context.Context, textRequest *relaymodel.GeneralOpenAIRequest, promptTokens int, ratio float64, meta *util.RelayMeta) (int, *relaymodel.ErrorWithStatusCode) {
preConsumedQuota := getPreConsumedQuota(textRequest, promptTokens, ratio) preConsumedQuota := getPreConsumedQuota(textRequest, promptTokens, ratio)
userQuota, err := model.CacheGetUserQuota(meta.UserId) userQuota, err := model.CacheGetUserQuota(ctx, meta.UserId)
if err != nil { if err != nil {
return preConsumedQuota, openai.ErrorWrapper(err, "get_user_quota_failed", http.StatusInternalServerError) return preConsumedQuota, openai.ErrorWrapper(err, "get_user_quota_failed", http.StatusInternalServerError)
} }
@ -168,7 +168,7 @@ func postConsumeQuota(ctx context.Context, usage *relaymodel.Usage, meta *util.R
if err != nil { if err != nil {
logger.Error(ctx, "error consuming token remain quota: "+err.Error()) logger.Error(ctx, "error consuming token remain quota: "+err.Error())
} }
err = model.CacheUpdateUserQuota(meta.UserId) err = model.CacheUpdateUserQuota(ctx, meta.UserId)
if err != nil { if err != nil {
logger.Error(ctx, "error update user quota cache: "+err.Error()) logger.Error(ctx, "error update user quota cache: "+err.Error())
} }

View File

@ -79,7 +79,7 @@ func RelayImageHelper(c *gin.Context, relayMode int) *relaymodel.ErrorWithStatus
modelRatio := common.GetModelRatio(imageRequest.Model) modelRatio := common.GetModelRatio(imageRequest.Model)
groupRatio := common.GetGroupRatio(meta.Group) groupRatio := common.GetGroupRatio(meta.Group)
ratio := modelRatio * groupRatio ratio := modelRatio * groupRatio
userQuota, err := model.CacheGetUserQuota(meta.UserId) userQuota, err := model.CacheGetUserQuota(ctx, meta.UserId)
quota := int(ratio*imageCostRatio*1000) * imageRequest.N quota := int(ratio*imageCostRatio*1000) * imageRequest.N
@ -125,7 +125,7 @@ func RelayImageHelper(c *gin.Context, relayMode int) *relaymodel.ErrorWithStatus
if err != nil { if err != nil {
logger.SysError("error consuming token remain quota: " + err.Error()) logger.SysError("error consuming token remain quota: " + err.Error())
} }
err = model.CacheUpdateUserQuota(meta.UserId) err = model.CacheUpdateUserQuota(ctx, meta.UserId)
if err != nil { if err != nil {
logger.SysError("error update user quota cache: " + err.Error()) logger.SysError("error update user quota cache: " + err.Error())
} }

View File

@ -161,7 +161,7 @@ func PostConsumeQuota(ctx context.Context, tokenId int, quotaDelta int, totalQuo
if err != nil { if err != nil {
logger.SysError("error consuming token remain quota: " + err.Error()) logger.SysError("error consuming token remain quota: " + err.Error())
} }
err = model.CacheUpdateUserQuota(userId) err = model.CacheUpdateUserQuota(ctx, userId)
if err != nil { if err != nil {
logger.SysError("error update user quota cache: " + err.Error()) logger.SysError("error update user quota cache: " + err.Error())
} }