蛋蛋星球-客户端
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

70 řádky
1.6 KiB

  1. package provider
  2. import (
  3. "applet/app/db"
  4. "code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
  5. "code.fnuoos.com/EggPlanet/egg_models.git/src/model"
  6. "encoding/json"
  7. "fmt"
  8. "sync"
  9. )
  10. var (
  11. instance *userInfoProvider //userInfoProvider 的单例实例
  12. once sync.Once
  13. )
  14. // UserInfoProvider 定义了一个接口来管理用户信息的获取
  15. type UserInfoProvider interface {
  16. GetUserInfo(uid int64) (*model.User, error)
  17. }
  18. // userInfoProvider 实现了 UserInfoProvider 接口
  19. type userInfoProvider struct {
  20. userCache map[int64]string
  21. mu sync.RWMutex
  22. }
  23. // GetUserInfoProvider 返回 userInfoProvider 的单例实例
  24. func GetUserInfoProvider() UserInfoProvider {
  25. once.Do(func() {
  26. instance = &userInfoProvider{
  27. userCache: make(map[int64]string),
  28. }
  29. })
  30. return instance
  31. }
  32. // GetUserInfo 根据用户名返回用户信息(TODO::支持多个goroutine并发执行)
  33. func (p *userInfoProvider) GetUserInfo(uid int64) (*model.User, error) {
  34. p.mu.RLock() //上"读"锁
  35. userStr, exists := p.userCache[uid]
  36. p.mu.RUnlock() //放"读"锁
  37. var userModel *model.User
  38. if exists {
  39. err := json.Unmarshal([]byte(userStr), &userModel)
  40. if err != nil {
  41. return nil, fmt.Errorf("failed to unmarshal user info: %w", err)
  42. }
  43. return userModel, nil
  44. }
  45. // 如果内存缓存中没有,则从 数据库查询
  46. newUserDb := implement.NewUserDb(db.Db)
  47. userModel, err := newUserDb.UserGetOneByParams(map[string]interface{}{
  48. "key": "id",
  49. "value": uid,
  50. })
  51. if err != nil {
  52. return userModel, err
  53. }
  54. // 缓存到内存中
  55. p.mu.Lock() //上"写"锁
  56. p.userCache[uid] = string(userStr)
  57. p.mu.Unlock() //放"写"锁
  58. return userModel, nil
  59. }