|
- package provider
-
- import (
- "applet/app/db"
- "code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
- "code.fnuoos.com/EggPlanet/egg_models.git/src/model"
- "encoding/json"
- "fmt"
- "sync"
- )
-
- var (
- instance *userInfoProvider //userInfoProvider 的单例实例
- once sync.Once
- )
-
- // UserInfoProvider 定义了一个接口来管理用户信息的获取
- type UserInfoProvider interface {
- GetUserInfo(uid int64) (*model.User, error)
- ClearCache()
- }
-
- // userInfoProvider 实现了 UserInfoProvider 接口
- type userInfoProvider struct {
- userCache map[int64]string
- mu sync.RWMutex
- }
-
- // NewUserInfoProvider 创建一个新的 userInfoProvider 实例
- func NewUserInfoProvider() UserInfoProvider {
- return &userInfoProvider{
- userCache: make(map[int64]string),
- }
- }
-
- // GetUserInfoProvider 返回 userInfoProvider 的单例实例
- func GetUserInfoProvider() UserInfoProvider {
- once.Do(func() {
- instance = &userInfoProvider{
- userCache: make(map[int64]string),
- }
- })
- return instance
- }
-
- // GetUserInfo 根据用户名返回用户信息(TODO::支持多个goroutine并发执行)
- func (p *userInfoProvider) GetUserInfo(uid int64) (*model.User, error) {
- p.mu.RLock() //上"读"锁
- userStr, exists := p.userCache[uid]
- p.mu.RUnlock() //放"读"锁
-
- var userModel *model.User
- if exists {
- err := json.Unmarshal([]byte(userStr), &userModel)
- if err != nil {
- return nil, fmt.Errorf("failed to unmarshal user info: %w", err)
- }
- return userModel, nil
- }
-
- // 如果内存缓存中没有,则从 数据库查询
- newUserDb := implement.NewUserDb(db.Db)
- userModel, err := newUserDb.UserGetOneByParams(map[string]interface{}{
- "key": "id",
- "value": uid,
- })
- if err != nil {
- return userModel, err
- }
-
- // 将用户信息转换为 JSON 字符串
- userBytes, err := json.Marshal(userModel)
- if err != nil {
- return nil, fmt.Errorf("failed to marshal user info: %w", err)
- }
- userStr = string(userBytes)
-
- // 缓存到内存中
- p.mu.Lock() //上"写"锁
- p.userCache[uid] = string(userStr)
- p.mu.Unlock() //放"写"锁
-
- return userModel, nil
- }
-
- // ClearCache 清空缓存
- func (p *userInfoProvider) ClearCache() {
- p.mu.Lock() // 上"写"锁
- p.userCache = make(map[int64]string)
- p.mu.Unlock() // 释放"写"锁
- }
|