123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- package history
- import (
- "context"
- hismodel "go-common/app/interface/main/history/model"
- "go-common/app/interface/main/tv/model/history"
- "go-common/library/log"
- "go-common/library/sync/errgroup"
- )
- const (
- _videoPGC = "pgc"
- _videoUGC = "archive"
- _typePGC = 1
- _typeUGC = 2
- )
- // pick history from cursor and cache, then compare to tell whether we could use cache or not
- func (s *Service) cacheHis(c context.Context, mid int64) (resp *history.RespCacheHis, err error) {
- var (
- cfg = s.conf.Cfg.HisCfg
- hismc *history.HisMC
- )
- resp = &history.RespCacheHis{
- UseCache: true,
- }
- if resp.Res, err = s.dao.Cursor(c, mid, 0, cfg.Pagesize, 0, cfg.Businesses); err != nil {
- log.Error("history dao.Cursor Mid %d, Err %v", mid, err)
- return
- }
- if len(resp.Res) == 0 {
- log.Info("Mid %d, No history", mid)
- return
- }
- if hismc, err = s.dao.HisCache(c, mid); err != nil {
- log.Error("history dao.HisCache Mid %d, Err %v", mid, err)
- return
- }
- if hismc != nil { // if the first item in cache and from cursor is the same, return with cache
- if resp.Res[0].Unix == hismc.LastViewAt {
- resp.Filtered = hismc.Res
- return
- }
- }
- resp.UseCache = false
- return
- }
- func (s *Service) combineHis(c context.Context, req *history.ReqCombineHis) (filtered []*history.HisRes) {
- var (
- durs = make(map[int64]int64)
- pgcRes, ugcRes []*hismodel.Resource
- pgcMap, ugcMap map[int64]*history.HisRes
- )
- g, _ := errgroup.WithContext(c)
- for _, v := range req.OriRes { // combine pgc & ugc data
- if v.Business == _videoPGC { // combine pgc history data
- if _, ok := req.OkSids[v.Sid]; !ok {
- continue
- }
- pgcRes = append(pgcRes, v)
- } else if v.Business == _videoUGC { // combine ugc history data
- if _, ok := req.OkAids[v.Oid]; !ok {
- continue
- }
- ugcRes = append(ugcRes, v)
- } else {
- continue
- }
- }
- okRes := mergeRes(pgcRes, ugcRes)
- g.Go(func() (err error) { // get pgc info
- pgcMap, err = s.pgcHisRes(context.Background(), pgcRes)
- return
- })
- g.Go(func() (err error) { // get ugc info
- ugcMap, err = s.ugcHisRes(context.Background(), ugcRes)
- return
- })
- g.Go(func() (err error) { // get duration info
- durs = s.getDuration(context.Background(), okRes)
- return nil
- })
- if err := g.Wait(); err != nil { // wait history combine media info
- log.Error("getHistory For Mid %d, Err %v", req.Mid, err)
- }
- for _, v := range okRes {
- var resrc *history.HisRes
- if v.Business == _videoPGC {
- if res, ok := pgcMap[v.Sid]; ok {
- resrc = res
- }
- } else if v.Business == _videoUGC {
- if res, ok := ugcMap[v.Oid]; ok {
- resrc = res
- }
- }
- if resrc == nil {
- log.Error("okRes Business %s, CID %d, %d, Empty", v.Business, v.Sid, v.Oid)
- continue
- }
- if dur, ok := durs[v.Oid]; ok { // duration
- resrc.PageDuration = dur
- }
- filtered = append(filtered, resrc)
- }
- return
- }
- // GetHistory picks history from rpc and combine the media data from Cache & DB
- func (s *Service) GetHistory(c context.Context, mid int64) (filtered []*history.HisRes, err error) {
- var respCache *history.RespCacheHis
- if respCache, err = s.cacheHis(c, mid); err != nil {
- return
- }
- if respCache.UseCache {
- return respCache.Filtered, nil
- }
- okSids, okAids := s.filterIDs(c, mid, respCache.Res)
- filtered = s.combineHis(c, &history.ReqCombineHis{
- Mid: mid,
- OkAids: okAids,
- OkSids: okSids,
- OriRes: respCache.Res,
- })
- s.dao.SaveHisCache(c, filtered)
- log.Info("Mid %d, OriLen %d, Filtered %d", mid, len(respCache.Res), len(filtered))
- return
- }
- // filterIDs picks the original history resource, arrange them into pgc and ugc and then filter by DAO
- func (s *Service) filterIDs(ctx context.Context, mid int64, res []*hismodel.Resource) (okSids, okAids map[int64]int) {
- var ugcAIDs, pgcSIDs []int64
- for _, v := range res { // we pick only pgc & archive from History rpc
- if v.Business == _videoPGC {
- pgcSIDs = append(pgcSIDs, v.Sid)
- } else if v.Business == _videoUGC {
- ugcAIDs = append(ugcAIDs, v.Oid)
- }
- }
- okSids, okAids = s.cmsDao.MixedFilter(ctx, pgcSIDs, ugcAIDs) // we filter the okSids and okAids
- log.Info("Mid %d, okSids %v, okAids %v", mid, okSids, okAids)
- return
- }
- // mergeRes merges two slices and return a new slice
- func mergeRes(s1 []*hismodel.Resource, s2 []*hismodel.Resource) []*hismodel.Resource {
- slice := make([]*hismodel.Resource, len(s1)+len(s2))
- copy(slice, s1)
- copy(slice[len(s1):], s2)
- return slice
- }
|