192 lines
4.4 KiB
Go
192 lines
4.4 KiB
Go
package service
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"go-common/library/conf/env"
|
||
"go-common/library/net/metadata"
|
||
|
||
"go-common/app/job/live/xroom-feed/internal/model"
|
||
"go-common/library/log"
|
||
"go-common/library/sync/errgroup"
|
||
"go-common/library/xstr"
|
||
)
|
||
|
||
const (
|
||
_whiteListType = 1
|
||
_condType = 2
|
||
_fileListType = 3
|
||
_areaType = "area"
|
||
_onlineType = "online"
|
||
_incomeType = "income"
|
||
_dmsType = "dms"
|
||
_liveDaysType = "live_days"
|
||
_hourRankType = "hour_rank"
|
||
_anchorCateType = "anchor_cate"
|
||
_roomStatusType = "room_status"
|
||
_condAnd = "and"
|
||
_condOr = "or"
|
||
|
||
_confTypeString = "string"
|
||
_confTypeRange = "range"
|
||
_confTypeTop = "top"
|
||
)
|
||
|
||
// JobTTl ...
|
||
type JobTTl struct {
|
||
ttl int
|
||
}
|
||
|
||
func (s *Service) reloadConfFromDb() {
|
||
t1 := time.NewTicker(time.Second * 5)
|
||
defer t1.Stop()
|
||
for {
|
||
select {
|
||
case <-t1.C:
|
||
confList, err := s.dao.GetConfFromDb()
|
||
if err != nil {
|
||
log.Error("[reloadConfFromDb]getConfFromDb_error:%+v", err)
|
||
continue
|
||
}
|
||
|
||
key, expire := s.getRecConfKey()
|
||
listStr, err := json.Marshal(confList)
|
||
if err == nil {
|
||
s.dao.SetRecPoolCache(context.TODO(), key, string(listStr), expire)
|
||
}
|
||
s.ruleConf.Store(confList)
|
||
}
|
||
}
|
||
}
|
||
|
||
func (s *Service) loadConfFromDb() {
|
||
confList, err := s.dao.GetConfFromDb()
|
||
if err != nil {
|
||
log.Error("[loadConfFromDb]getConfFromDb_error:%+v", err)
|
||
return
|
||
}
|
||
s.ruleConf.Store(confList)
|
||
}
|
||
|
||
func (s *Service) parseCondConf(cond string) (condConf *model.RuleProtocol, err error) {
|
||
condConf = new(model.RuleProtocol)
|
||
err = json.Unmarshal([]byte(cond), &condConf)
|
||
if err != nil {
|
||
log.Error("[parseCondConf]Unmarshal err: %+v", err)
|
||
return
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
func (s *Service) reloadRecList() {
|
||
t1 := time.NewTicker(time.Second * 20)
|
||
defer t1.Stop()
|
||
for {
|
||
select {
|
||
case <-t1.C:
|
||
s.genRecListJob()
|
||
}
|
||
}
|
||
}
|
||
|
||
// 对所有配置的规则取数据的主程序
|
||
func (s *Service) genRecListJob() {
|
||
log.Info("[genRecListJob]genRecListJob start")
|
||
ttl := 20
|
||
ttl, err := s.ac.Get("JobTtl").Int()
|
||
if err != nil {
|
||
log.Error("[genRecListJob]getJobTtlConfFromSven_error:%+v", err)
|
||
}
|
||
confList := s.ruleConf.Load()
|
||
// assert
|
||
res, ok := confList.([]*model.RecPoolConf)
|
||
if !ok {
|
||
log.Error("[genRecListJob]conf assert error! %+v", confList)
|
||
return
|
||
}
|
||
if len(res) <= 0 {
|
||
log.Warn("[genRecListJob]confList_empty")
|
||
return
|
||
}
|
||
|
||
//可配置时间结束子任务 内部要有阻塞操作
|
||
cCtx := metadata.NewContext(context.TODO(), metadata.MD{metadata.Color: env.Color})
|
||
ctx, cancel := context.WithTimeout(cCtx, time.Duration(ttl)*time.Second)
|
||
wg := errgroup.Group{}
|
||
|
||
// 每条规则之间无关联,可以不互相cancel,只看超时ctx (可在内部对每个操作设置)
|
||
// 规则获取loop
|
||
for _, rule := range res {
|
||
// 白名单规则
|
||
if rule.ConfType == _whiteListType || rule.ConfType == _fileListType {
|
||
ruleId := rule.Id
|
||
wg.Go(func() error {
|
||
listStr, err := s.dao.GetWhiteList(ctx, ruleId)
|
||
if err != nil {
|
||
log.Error("[genRecListJob]GetWhiteList_err:%+v", err)
|
||
return nil
|
||
}
|
||
|
||
listStrArr := strings.Split(listStr, ",")
|
||
listIntArr := make([]int64, 0)
|
||
for _, roomIdStr := range listStrArr {
|
||
roomIdInt, _ := strconv.ParseInt(roomIdStr, 10, 64)
|
||
listIntArr = append(listIntArr, roomIdInt)
|
||
}
|
||
|
||
if len(listIntArr) > 0 {
|
||
ids := s.setRecInfoCache(ctx, listIntArr)
|
||
key, expire := s.getRecPoolKey(ruleId)
|
||
s.dao.SetRecPoolCache(ctx, key, xstr.JoinInts(ids), expire)
|
||
}
|
||
return nil
|
||
})
|
||
}
|
||
|
||
// 条件规则
|
||
if rule.ConfType == _condType {
|
||
ruleId := rule.Id
|
||
ruleStr := rule.Rules
|
||
wg.Go(func() error {
|
||
condConf, err := s.parseCondConf(ruleStr)
|
||
if err != nil {
|
||
log.Error("[genRecListJob]parseCondConf_err:%+v", err)
|
||
return nil
|
||
}
|
||
if len(condConf.Condition) == 0 {
|
||
log.Error("[genRecListJob]parseCondConf_empty")
|
||
return nil
|
||
}
|
||
roomIds := s.genCondConfRoomList(ctx, condConf.Condition, condConf.Cond, ruleId)
|
||
|
||
if len(roomIds) > 0 {
|
||
ids := s.setRecInfoCache(ctx, roomIds)
|
||
key, expire := s.getRecPoolKey(ruleId)
|
||
s.dao.SetRecPoolCache(ctx, key, xstr.JoinInts(ids), expire)
|
||
}
|
||
return nil
|
||
})
|
||
}
|
||
}
|
||
|
||
// 超时检测
|
||
select {
|
||
case <-ctx.Done():
|
||
{
|
||
log.Info("[genRecListJob]job time out: %d", ttl)
|
||
cancel()
|
||
}
|
||
}
|
||
|
||
err = wg.Wait()
|
||
if err != nil {
|
||
log.Error("[genRecListJob]rule loop wait err:%+v", err)
|
||
}
|
||
log.Info("[genRecListJob]genRecListJob done")
|
||
}
|