rank.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package v2
  2. import (
  3. "context"
  4. "strconv"
  5. "sync/atomic"
  6. "time"
  7. bp "go-common/app/interface/live/app-interface/api/http/v2"
  8. "go-common/app/interface/live/app-interface/dao"
  9. "go-common/app/service/live/room/api/liverpc/v1"
  10. accountM "go-common/app/service/main/account/model"
  11. "go-common/library/log"
  12. "go-common/library/sync/errgroup"
  13. )
  14. type lastHourCache struct {
  15. Modules []*bp.MHourRank
  16. CTime int64
  17. }
  18. const (
  19. _hourRankType = 5
  20. )
  21. var LastHourItemCache atomic.Value
  22. // 获取首页上小时排行榜
  23. func (s *IndexService) getLastHourTop3(ctx context.Context) (resp []*bp.MHourRank, err error) {
  24. moduleInfoMaps := s.GetAllModuleInfoMapFromCache(ctx)
  25. resp = []*bp.MHourRank{}
  26. module, ok := moduleInfoMaps[_hourRankType]
  27. if !ok || 0 == len(module) {
  28. return
  29. }
  30. cacheResp, err := getLastHour3FromCache(ctx)
  31. if 0 != len(cacheResp) && 0 != len(cacheResp[0].List) {
  32. resp = cacheResp
  33. return
  34. }
  35. // load
  36. resp, err = s.loadLastHourData(ctx)
  37. return
  38. }
  39. func setLastHour3Cache(c context.Context, modules []*bp.MHourRank) {
  40. cache := &lastHourCache{
  41. Modules: modules,
  42. CTime: time.Now().Unix(),
  43. }
  44. LastHourItemCache.Store(cache)
  45. return
  46. }
  47. func getLastHour3FromCache(c context.Context) (resp []*bp.MHourRank, err error) {
  48. resp = make([]*bp.MHourRank, 0)
  49. now := time.Now().Unix()
  50. resp = []*bp.MHourRank{}
  51. cache, ok := LastHourItemCache.Load().(*lastHourCache)
  52. if !ok || nil == cache {
  53. return
  54. }
  55. cTime := cache.CTime
  56. if now > (cTime + 60) {
  57. return
  58. }
  59. resp = cache.Modules
  60. return
  61. }
  62. // loadLastHour 定时存cache
  63. func (s *IndexService) loadLastHour() {
  64. for {
  65. time.Sleep(time.Second * 20)
  66. s.loadLastHourData(context.TODO())
  67. }
  68. }
  69. // loadLastHourData 获取上小时榜数据
  70. func (s *IndexService) loadLastHourData(ctx context.Context) (resp []*bp.MHourRank, err error) {
  71. moduleInfoMaps := s.GetAllModuleInfoMapFromCache(ctx)
  72. resp = []*bp.MHourRank{}
  73. module, ok := moduleInfoMaps[_hourRankType]
  74. if !ok || 0 == len(module) {
  75. return
  76. }
  77. // extraInfo format
  78. var nowHourName string
  79. lastHourName := time.Now().Add(-time.Hour).Format("15")
  80. timeNum, _ := strconv.Atoi(lastHourName)
  81. lastHourName += ":00"
  82. if timeNum > 9 {
  83. nowHourName = strconv.Itoa(timeNum + 1)
  84. } else {
  85. nowHourName = time.Now().Format("15")
  86. }
  87. nowHourName += ":00"
  88. subTitle := lastHourName + "-" + nowHourName + " 总榜排名"
  89. list := []*bp.HourRankItem{}
  90. roomReq := &v1.RoomGetStatusInfoByUidsReq{}
  91. roomResp := &v1.RoomGetStatusInfoByUidsResp{}
  92. userInfo := map[int64]*accountM.Card{}
  93. wg := &errgroup.Group{}
  94. // liveRpc call rankdb
  95. uids, err := s.rankdbDao.GetLastHourTop3(ctx)
  96. if 0 == len(uids) || nil != err {
  97. goto formatReturn
  98. }
  99. wg, _ = errgroup.WithContext(ctx)
  100. wg.Go(func() error {
  101. // liveRpc call room
  102. roomReq.Uids = uids
  103. roomResp, err = dao.RoomApi.V1Room.GetStatusInfoByUids(ctx, roomReq)
  104. return err
  105. })
  106. wg.Go(func() error {
  107. // call account for UserInfo
  108. userInfo, err = s.rankdbDao.GetUserInfoData(ctx, uids)
  109. return err
  110. })
  111. if err = wg.Wait(); nil != err {
  112. goto formatReturn
  113. }
  114. if 0 != roomResp.Code || 0 == len(roomResp.Data) {
  115. log.Error("[app-interface][rankDbItem] liveRpc call room return error, code:%d, msg:%s", roomResp.Code, roomResp.Data)
  116. goto formatReturn
  117. }
  118. if 0 == len(userInfo) {
  119. log.Error("[app-interface][rankDbItem] call account return empty")
  120. goto formatReturn
  121. }
  122. for k, v := range uids {
  123. detail := &bp.HourRankItem{}
  124. if nil != roomResp.Data[v] {
  125. detail = &bp.HourRankItem{
  126. Roomid: roomResp.Data[v].RoomId,
  127. LiveStatus: roomResp.Data[v].LiveStatus,
  128. AreaV2ParentId: roomResp.Data[v].AreaV2ParentId,
  129. AreaV2Id: roomResp.Data[v].AreaV2Id,
  130. AreaV2ParentName: roomResp.Data[v].AreaV2ParentName,
  131. AreaV2Name: roomResp.Data[v].AreaV2Name,
  132. Uname: userInfo[v].Name,
  133. Face: userInfo[v].Face,
  134. }
  135. }
  136. if nil != userInfo[v] {
  137. detail.Uname = userInfo[v].Name
  138. detail.Face = userInfo[v].Face
  139. }
  140. detail.Rank = int64(k + 1)
  141. detail.Uid = v
  142. list = append(list, detail)
  143. }
  144. // format return
  145. formatReturn:
  146. for _, v := range module {
  147. if v.Type == _hourRankType {
  148. item := &bp.MHourRank{
  149. ModuleInfo: v,
  150. ExtraInfo: &bp.HourRankExtra{SubTitle: subTitle},
  151. List: list,
  152. }
  153. resp = append(resp, item)
  154. break
  155. }
  156. }
  157. moduleCache := resp
  158. setLastHour3Cache(ctx, moduleCache)
  159. return
  160. }