Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"combine.go",
"history.go",
"service.go",
],
importpath = "go-common/app/interface/main/tv/service/history",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/history/model:go_default_library",
"//app/interface/main/tv/conf:go_default_library",
"//app/interface/main/tv/dao/archive:go_default_library",
"//app/interface/main/tv/dao/cms:go_default_library",
"//app/interface/main/tv/dao/history:go_default_library",
"//app/interface/main/tv/model:go_default_library",
"//app/interface/main/tv/model/history:go_default_library",
"//library/log:go_default_library",
"//library/sync/errgroup:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = ["service_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/tv/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,147 @@
package history
import (
"context"
hismdl "go-common/app/interface/main/history/model"
"go-common/app/interface/main/tv/model"
"go-common/app/interface/main/tv/model/history"
"go-common/library/log"
)
func (s *Service) pgcHisRes(ctx context.Context, res []*hismdl.Resource) (resMap map[int64]*history.HisRes, err error) {
var (
snMetas map[int64]*model.SeasonCMS
epMetas map[int64]*model.EpCMS
pickSids []int64
pickEpids []int64
)
resMap = make(map[int64]*history.HisRes)
for _, v := range res {
pickSids = append(pickSids, v.Sid)
pickEpids = append(pickEpids, v.Epid)
}
if snMetas, err = s.cmsDao.LoadSnsCMSMap(ctx, pickSids); err != nil {
log.Error("LoadSnsCMS Sids %v, Err %v", pickSids, err)
return
}
if epMetas, err = s.cmsDao.LoadEpsCMS(ctx, pickEpids); err != nil {
log.Warn("LoadEpsCMS Epids %v, Err %v", pickEpids, err)
err = nil
}
for _, v := range res {
his := hisTrans(v)
his.Type = _typePGC
his.Page = nil
// season info
snMeta, okS := snMetas[v.Sid]
if !okS {
log.Error("pgcHisRes Missing Info Sid %d", v.Sid)
continue
}
his.Title = snMeta.Title
his.Cover = snMeta.Cover
if snMeta.NeedVip() { // add vip corner mark
his.CornerMark = &(*s.conf.Cfg.SnVipCorner)
}
// ep info
epMeta, okE := epMetas[v.Epid]
if !okE {
log.Warn("pgcHisRes Missing Info Epid %d", v.Epid)
} else {
his.EPMeta = &history.HisEP{
EPID: epMeta.EPID,
Cover: epMeta.Cover,
Title: epMeta.Subtitle,
LongTitle: epMeta.Title,
}
}
resMap[v.Sid] = his
}
return
}
func (s *Service) ugcHisRes(ctx context.Context, res []*hismdl.Resource) (resMap map[int64]*history.HisRes, err error) {
var (
arcMetas map[int64]*model.ArcCMS
videoMetas map[int64]*model.VideoCMS
pickAids []int64
pickCids []int64
)
resMap = make(map[int64]*history.HisRes)
for _, v := range res {
pickAids = append(pickAids, v.Oid)
pickCids = append(pickCids, v.Cid)
}
if arcMetas, err = s.cmsDao.LoadArcsMediaMap(ctx, pickAids); err != nil {
log.Error("LoadArcsMediaMap Sids %v, Err %v", pickAids, err)
return
}
if videoMetas, err = s.cmsDao.LoadVideosMeta(ctx, pickCids); err != nil {
log.Warn("LoadVideosMeta Epids %v, Err %v", pickCids, err)
err = nil
}
for _, v := range res {
his := hisTrans(v)
his.Type = _typeUGC
his.Page = nil
// season info
arcMeta, okS := arcMetas[v.Oid]
if !okS {
log.Error("ugcHisRes Missing Info Aid %d", v.Oid)
continue
}
his.Title = arcMeta.Title
his.Cover = arcMeta.Cover
// ep info
video, okE := videoMetas[v.Cid]
if !okE {
log.Warn("ugcHisRes Missing Info Cid %d", v.Cid)
} else {
his.Page = &history.HisPage{
CID: video.CID,
Part: video.Title,
Page: video.IndexOrder,
}
}
resMap[v.Oid] = his
}
return
}
func hisTrans(res *hismdl.Resource) *history.HisRes {
return &history.HisRes{
Mid: res.Mid,
Oid: res.Oid,
Sid: res.Sid,
Epid: res.Epid,
Cid: res.Cid,
Business: res.Business,
DT: res.DT,
Pro: res.Pro,
Unix: res.Unix,
Type: _typePGC,
}
}
func (s *Service) getDuration(ctx context.Context, res []*hismdl.Resource) (durs map[int64]int64) {
var (
aids []int64
)
durs = make(map[int64]int64)
for _, v := range res {
aids = append(aids, v.Oid)
}
resMeta := s.arcDao.LoadViews(ctx, aids)
for _, v := range res {
if view, ok := resMeta[v.Oid]; ok && len(view.Pages) > 0 {
for _, vp := range view.Pages {
if v.Cid == vp.Cid {
durs[v.Oid] = vp.Duration
break
}
}
}
}
return
}

View File

@@ -0,0 +1,152 @@
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
}

View File

@@ -0,0 +1,27 @@
package history
import (
"go-common/app/interface/main/tv/conf"
"go-common/app/interface/main/tv/dao/archive"
"go-common/app/interface/main/tv/dao/cms"
"go-common/app/interface/main/tv/dao/history"
)
// Service .
type Service struct {
conf *conf.Config
dao *history.Dao
cmsDao *cms.Dao
arcDao *archive.Dao
}
// New .
func New(c *conf.Config) *Service {
srv := &Service{
conf: c,
dao: history.New(c),
cmsDao: cms.New(c),
arcDao: archive.New(c),
}
return srv
}

View File

@@ -0,0 +1,45 @@
package history
import (
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/tv/conf"
"context"
"encoding/json"
"fmt"
. "github.com/smartystreets/goconvey/convey"
)
var (
srv *Service
)
func init() {
dir, _ := filepath.Abs("../../cmd/tv-interface.toml")
flag.Set("conf", dir)
conf.Init()
srv = New(conf.Conf)
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
Reset(func() {})
f(srv)
}
}
func TestService_GetHistory(t *testing.T) {
Convey("TestService_GetHistory", t, WithService(func(s *Service) {
cont, err := s.GetHistory(context.Background(), int64(27515401))
So(err, ShouldBeNil)
data, _ := json.Marshal(cont)
fmt.Println(string(data))
}))
}