蛋蛋星球-客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

92 lines
2.2 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. ClearCache()
  18. }
  19. // userInfoProvider 实现了 UserInfoProvider 接口
  20. type userInfoProvider struct {
  21. userCache map[int64]string
  22. mu sync.RWMutex
  23. }
  24. // NewUserInfoProvider 创建一个新的 userInfoProvider 实例
  25. func NewUserInfoProvider() UserInfoProvider {
  26. return &userInfoProvider{
  27. userCache: make(map[int64]string),
  28. }
  29. }
  30. // GetUserInfoProvider 返回 userInfoProvider 的单例实例
  31. func GetUserInfoProvider() UserInfoProvider {
  32. once.Do(func() {
  33. instance = &userInfoProvider{
  34. userCache: make(map[int64]string),
  35. }
  36. })
  37. return instance
  38. }
  39. // GetUserInfo 根据用户名返回用户信息(TODO::支持多个goroutine并发执行)
  40. func (p *userInfoProvider) GetUserInfo(uid int64) (*model.User, error) {
  41. p.mu.RLock() //上"读"锁
  42. userStr, exists := p.userCache[uid]
  43. p.mu.RUnlock() //放"读"锁
  44. var userModel *model.User
  45. if exists {
  46. err := json.Unmarshal([]byte(userStr), &userModel)
  47. if err != nil {
  48. return nil, fmt.Errorf("failed to unmarshal user info: %w", err)
  49. }
  50. return userModel, nil
  51. }
  52. // 如果内存缓存中没有,则从 数据库查询
  53. newUserDb := implement.NewUserDb(db.Db)
  54. userModel, err := newUserDb.UserGetOneByParams(map[string]interface{}{
  55. "key": "id",
  56. "value": uid,
  57. })
  58. if err != nil {
  59. return userModel, err
  60. }
  61. // 将用户信息转换为 JSON 字符串
  62. userBytes, err := json.Marshal(userModel)
  63. if err != nil {
  64. return nil, fmt.Errorf("failed to marshal user info: %w", err)
  65. }
  66. userStr = string(userBytes)
  67. // 缓存到内存中
  68. p.mu.Lock() //上"写"锁
  69. p.userCache[uid] = string(userStr)
  70. p.mu.Unlock() //放"写"锁
  71. return userModel, nil
  72. }
  73. // ClearCache 清空缓存
  74. func (p *userInfoProvider) ClearCache() {
  75. p.mu.Lock() // 上"写"锁
  76. p.userCache = make(map[int64]string)
  77. p.mu.Unlock() // 释放"写"锁
  78. }