This commit refactors the logging mechanism across the application by replacing direct logger calls with a centralized logging approach using the `common` package. Key changes include: - Replaced instances of `logger.SysLog` and `logger.FatalLog` with `common.SysLog` and `common.FatalLog` for consistent logging practices. - Updated resource initialization error handling to utilize the new logging structure, enhancing maintainability and readability. - Minor adjustments to improve code clarity and organization throughout various modules. This change aims to streamline logging and improve the overall architecture of the codebase.
219 lines
5.3 KiB
Go
219 lines
5.3 KiB
Go
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"one-api/common"
|
|
"one-api/constant"
|
|
"one-api/dto"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/bytedance/gopkg/util/gopool"
|
|
)
|
|
|
|
// UserBase struct remains the same as it represents the cached data structure
|
|
type UserBase struct {
|
|
Id int `json:"id"`
|
|
Group string `json:"group"`
|
|
Email string `json:"email"`
|
|
Quota int `json:"quota"`
|
|
Status int `json:"status"`
|
|
Username string `json:"username"`
|
|
Setting string `json:"setting"`
|
|
}
|
|
|
|
func (user *UserBase) WriteContext(c *gin.Context) {
|
|
common.SetContextKey(c, constant.ContextKeyUserGroup, user.Group)
|
|
common.SetContextKey(c, constant.ContextKeyUserQuota, user.Quota)
|
|
common.SetContextKey(c, constant.ContextKeyUserStatus, user.Status)
|
|
common.SetContextKey(c, constant.ContextKeyUserEmail, user.Email)
|
|
common.SetContextKey(c, constant.ContextKeyUserName, user.Username)
|
|
common.SetContextKey(c, constant.ContextKeyUserSetting, user.GetSetting())
|
|
}
|
|
|
|
func (user *UserBase) GetSetting() dto.UserSetting {
|
|
setting := dto.UserSetting{}
|
|
if user.Setting != "" {
|
|
err := common.Unmarshal([]byte(user.Setting), &setting)
|
|
if err != nil {
|
|
common.SysLog("failed to unmarshal setting: " + err.Error())
|
|
}
|
|
}
|
|
return setting
|
|
}
|
|
|
|
// getUserCacheKey returns the key for user cache
|
|
func getUserCacheKey(userId int) string {
|
|
return fmt.Sprintf("user:%d", userId)
|
|
}
|
|
|
|
// invalidateUserCache clears user cache
|
|
func invalidateUserCache(userId int) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
return common.RedisDelKey(getUserCacheKey(userId))
|
|
}
|
|
|
|
// updateUserCache updates all user cache fields using hash
|
|
func updateUserCache(user User) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
|
|
return common.RedisHSetObj(
|
|
getUserCacheKey(user.Id),
|
|
user.ToBaseUser(),
|
|
time.Duration(common.RedisKeyCacheSeconds())*time.Second,
|
|
)
|
|
}
|
|
|
|
// GetUserCache gets complete user cache from hash
|
|
func GetUserCache(userId int) (userCache *UserBase, err error) {
|
|
var user *User
|
|
var fromDB bool
|
|
defer func() {
|
|
// Update Redis cache asynchronously on successful DB read
|
|
if shouldUpdateRedis(fromDB, err) && user != nil {
|
|
gopool.Go(func() {
|
|
if err := updateUserCache(*user); err != nil {
|
|
common.SysLog("failed to update user status cache: " + err.Error())
|
|
}
|
|
})
|
|
}
|
|
}()
|
|
|
|
// Try getting from Redis first
|
|
userCache, err = cacheGetUserBase(userId)
|
|
if err == nil {
|
|
return userCache, nil
|
|
}
|
|
|
|
// If Redis fails, get from DB
|
|
fromDB = true
|
|
user, err = GetUserById(userId, false)
|
|
if err != nil {
|
|
return nil, err // Return nil and error if DB lookup fails
|
|
}
|
|
|
|
// Create cache object from user data
|
|
userCache = &UserBase{
|
|
Id: user.Id,
|
|
Group: user.Group,
|
|
Quota: user.Quota,
|
|
Status: user.Status,
|
|
Username: user.Username,
|
|
Setting: user.Setting,
|
|
Email: user.Email,
|
|
}
|
|
|
|
return userCache, nil
|
|
}
|
|
|
|
func cacheGetUserBase(userId int) (*UserBase, error) {
|
|
if !common.RedisEnabled {
|
|
return nil, fmt.Errorf("redis is not enabled")
|
|
}
|
|
var userCache UserBase
|
|
// Try getting from Redis first
|
|
err := common.RedisHGetObj(getUserCacheKey(userId), &userCache)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &userCache, nil
|
|
}
|
|
|
|
// Add atomic quota operations using hash fields
|
|
func cacheIncrUserQuota(userId int, delta int64) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
return common.RedisHIncrBy(getUserCacheKey(userId), "Quota", delta)
|
|
}
|
|
|
|
func cacheDecrUserQuota(userId int, delta int64) error {
|
|
return cacheIncrUserQuota(userId, -delta)
|
|
}
|
|
|
|
// Helper functions to get individual fields if needed
|
|
func getUserGroupCache(userId int) (string, error) {
|
|
cache, err := GetUserCache(userId)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return cache.Group, nil
|
|
}
|
|
|
|
func getUserQuotaCache(userId int) (int, error) {
|
|
cache, err := GetUserCache(userId)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return cache.Quota, nil
|
|
}
|
|
|
|
func getUserStatusCache(userId int) (int, error) {
|
|
cache, err := GetUserCache(userId)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return cache.Status, nil
|
|
}
|
|
|
|
func getUserNameCache(userId int) (string, error) {
|
|
cache, err := GetUserCache(userId)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return cache.Username, nil
|
|
}
|
|
|
|
func getUserSettingCache(userId int) (dto.UserSetting, error) {
|
|
cache, err := GetUserCache(userId)
|
|
if err != nil {
|
|
return dto.UserSetting{}, err
|
|
}
|
|
return cache.GetSetting(), nil
|
|
}
|
|
|
|
// New functions for individual field updates
|
|
func updateUserStatusCache(userId int, status bool) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
statusInt := common.UserStatusEnabled
|
|
if !status {
|
|
statusInt = common.UserStatusDisabled
|
|
}
|
|
return common.RedisHSetField(getUserCacheKey(userId), "Status", fmt.Sprintf("%d", statusInt))
|
|
}
|
|
|
|
func updateUserQuotaCache(userId int, quota int) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
return common.RedisHSetField(getUserCacheKey(userId), "Quota", fmt.Sprintf("%d", quota))
|
|
}
|
|
|
|
func updateUserGroupCache(userId int, group string) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
return common.RedisHSetField(getUserCacheKey(userId), "Group", group)
|
|
}
|
|
|
|
func updateUserNameCache(userId int, username string) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
return common.RedisHSetField(getUserCacheKey(userId), "Username", username)
|
|
}
|
|
|
|
func updateUserSettingCache(userId int, setting string) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
return common.RedisHSetField(getUserCacheKey(userId), "Setting", setting)
|
|
}
|