bilibili-backup/app/interface/live/app-interface/service/v2/rank.go
2019-04-22 02:59:20 +00:00

181 lines
4.3 KiB
Go

package v2
import (
"context"
"strconv"
"sync/atomic"
"time"
bp "go-common/app/interface/live/app-interface/api/http/v2"
"go-common/app/interface/live/app-interface/dao"
"go-common/app/service/live/room/api/liverpc/v1"
accountM "go-common/app/service/main/account/model"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
type lastHourCache struct {
Modules []*bp.MHourRank
CTime int64
}
const (
_hourRankType = 5
)
var LastHourItemCache atomic.Value
// 获取首页上小时排行榜
func (s *IndexService) getLastHourTop3(ctx context.Context) (resp []*bp.MHourRank, err error) {
moduleInfoMaps := s.GetAllModuleInfoMapFromCache(ctx)
resp = []*bp.MHourRank{}
module, ok := moduleInfoMaps[_hourRankType]
if !ok || 0 == len(module) {
return
}
cacheResp, err := getLastHour3FromCache(ctx)
if 0 != len(cacheResp) && 0 != len(cacheResp[0].List) {
resp = cacheResp
return
}
// load
resp, err = s.loadLastHourData(ctx)
return
}
func setLastHour3Cache(c context.Context, modules []*bp.MHourRank) {
cache := &lastHourCache{
Modules: modules,
CTime: time.Now().Unix(),
}
LastHourItemCache.Store(cache)
return
}
func getLastHour3FromCache(c context.Context) (resp []*bp.MHourRank, err error) {
resp = make([]*bp.MHourRank, 0)
now := time.Now().Unix()
resp = []*bp.MHourRank{}
cache, ok := LastHourItemCache.Load().(*lastHourCache)
if !ok || nil == cache {
return
}
cTime := cache.CTime
if now > (cTime + 60) {
return
}
resp = cache.Modules
return
}
// loadLastHour 定时存cache
func (s *IndexService) loadLastHour() {
for {
time.Sleep(time.Second * 20)
s.loadLastHourData(context.TODO())
}
}
// loadLastHourData 获取上小时榜数据
func (s *IndexService) loadLastHourData(ctx context.Context) (resp []*bp.MHourRank, err error) {
moduleInfoMaps := s.GetAllModuleInfoMapFromCache(ctx)
resp = []*bp.MHourRank{}
module, ok := moduleInfoMaps[_hourRankType]
if !ok || 0 == len(module) {
return
}
// extraInfo format
var nowHourName string
lastHourName := time.Now().Add(-time.Hour).Format("15")
timeNum, _ := strconv.Atoi(lastHourName)
lastHourName += ":00"
if timeNum > 9 {
nowHourName = strconv.Itoa(timeNum + 1)
} else {
nowHourName = time.Now().Format("15")
}
nowHourName += ":00"
subTitle := lastHourName + "-" + nowHourName + " 总榜排名"
list := []*bp.HourRankItem{}
roomReq := &v1.RoomGetStatusInfoByUidsReq{}
roomResp := &v1.RoomGetStatusInfoByUidsResp{}
userInfo := map[int64]*accountM.Card{}
wg := &errgroup.Group{}
// liveRpc call rankdb
uids, err := s.rankdbDao.GetLastHourTop3(ctx)
if 0 == len(uids) || nil != err {
goto formatReturn
}
wg, _ = errgroup.WithContext(ctx)
wg.Go(func() error {
// liveRpc call room
roomReq.Uids = uids
roomResp, err = dao.RoomApi.V1Room.GetStatusInfoByUids(ctx, roomReq)
return err
})
wg.Go(func() error {
// call account for UserInfo
userInfo, err = s.rankdbDao.GetUserInfoData(ctx, uids)
return err
})
if err = wg.Wait(); nil != err {
goto formatReturn
}
if 0 != roomResp.Code || 0 == len(roomResp.Data) {
log.Error("[app-interface][rankDbItem] liveRpc call room return error, code:%d, msg:%s", roomResp.Code, roomResp.Data)
goto formatReturn
}
if 0 == len(userInfo) {
log.Error("[app-interface][rankDbItem] call account return empty")
goto formatReturn
}
for k, v := range uids {
detail := &bp.HourRankItem{}
if nil != roomResp.Data[v] {
detail = &bp.HourRankItem{
Roomid: roomResp.Data[v].RoomId,
LiveStatus: roomResp.Data[v].LiveStatus,
AreaV2ParentId: roomResp.Data[v].AreaV2ParentId,
AreaV2Id: roomResp.Data[v].AreaV2Id,
AreaV2ParentName: roomResp.Data[v].AreaV2ParentName,
AreaV2Name: roomResp.Data[v].AreaV2Name,
Uname: userInfo[v].Name,
Face: userInfo[v].Face,
}
}
if nil != userInfo[v] {
detail.Uname = userInfo[v].Name
detail.Face = userInfo[v].Face
}
detail.Rank = int64(k + 1)
detail.Uid = v
list = append(list, detail)
}
// format return
formatReturn:
for _, v := range module {
if v.Type == _hourRankType {
item := &bp.MHourRank{
ModuleInfo: v,
ExtraInfo: &bp.HourRankExtra{SubTitle: subTitle},
List: list,
}
resp = append(resp, item)
break
}
}
moduleCache := resp
setLastHour3Cache(ctx, moduleCache)
return
}