202 lines
5.6 KiB
Go
202 lines
5.6 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"go-common/app/job/main/click/model"
|
|
"go-common/library/log"
|
|
)
|
|
|
|
func (s *Service) isAllow(ctx context.Context, c *model.ClickMsg) (rtype int8, err error) {
|
|
var (
|
|
f *model.Forbid
|
|
ok bool
|
|
duration int64
|
|
)
|
|
rtype = model.LogTypeForNotUse
|
|
// 自动播放的恶心逻辑 开始
|
|
if c.Plat == model.PlatForAutoPlayAndroid || c.Plat == model.PlatForAutoPlayInlineAndroid || c.Plat == model.PlatForAutoPlayIOS || c.Plat == model.PlafForAutoPlayInlineIOS ||
|
|
strings.Contains(c.UserAgent, "(inline_play_begin)") { // plat的逻辑更换为UA中添加(inline_play_begin)
|
|
log.Warn("no count! hit autoplay plat(%d) aid(%d)", c.Plat, c.AID)
|
|
rtype = model.LogTypeForInlineBegin // 2
|
|
if c.Buvid != "" {
|
|
if err = s.setRealDid(ctx, c.Buvid, c.AID, c.Did); err != nil {
|
|
log.Error("s.setRealDid(%s, %s) error(%v)", c.Buvid, c.Did, err)
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
// 自动播放的恶心逻辑 结束
|
|
if c.MID > 0 {
|
|
if _, ok := s.forbidMids[c.MID]; ok {
|
|
log.Warn("mid(%d) forbidden", c.MID)
|
|
return
|
|
}
|
|
}
|
|
if f, ok = s.forbids[c.AID][c.Plat]; ok {
|
|
if f.Lv == -2 && (strings.HasSuffix(c.UserAgent, "(no_accesskey)") || c.MID == 0) {
|
|
log.Warn("no count! hit no_accesskey! agent(%s) aid(%d) mid(%d) plat(%d)", c.UserAgent, c.AID, c.MID, c.Plat)
|
|
return
|
|
} else if f.Lv == -1 && c.MID == 0 {
|
|
// 游客不计算点击数
|
|
log.Warn("no count! hit forbid_lv(%d) mid(%d)", f.Lv, c.MID)
|
|
return
|
|
} else if f.Lv >= 0 && (c.Lv <= f.Lv || c.MID == 0) {
|
|
// 游客和低于锁定等级的不计算点击数
|
|
return
|
|
}
|
|
}
|
|
if c.EpID > 0 {
|
|
if err = s.checkEpAvRelation(ctx, c.AID, c.EpID, c.SeasonType); err != nil {
|
|
log.Error("s.getOid(%d, %d, %d) error(%v)", c.AID, c.EpID, c.SeasonType)
|
|
return
|
|
}
|
|
}
|
|
if !s.canCount(ctx, c.AID, c.EpID, c.IP, c.STime, c.Did) {
|
|
log.Warn("same ip(%s) and av(%d) replay", c.IP, c.AID)
|
|
return
|
|
}
|
|
duration = s.ArcDuration(ctx, c.AID)
|
|
if s.isReplay(ctx, c.MID, c.AID, c.Did, duration) {
|
|
log.Warn("mid(%d) bvid(%s) aid(%d) epid(%d) isPGC(%v) gapTime(%d) is replay", c.MID, c.Did, c.AID, c.EpID, c.EpID > 0, duration)
|
|
return
|
|
}
|
|
rtype = model.LogTypeForTurly // 1
|
|
return
|
|
}
|
|
|
|
func (s *Service) checkEpAvRelation(ctx context.Context, aid, epid int64, seasonType int) (err error) {
|
|
s.etamMutex.RLock()
|
|
_, ok := s.eTam[epid]
|
|
s.etamMutex.RUnlock()
|
|
if ok {
|
|
return
|
|
}
|
|
var isLegal bool
|
|
if isLegal, err = s.db.IsLegal(ctx, aid, epid, seasonType); err != nil {
|
|
// 接口请求失败时按ugc维度走
|
|
err = nil
|
|
} else if !isLegal {
|
|
// epid not exist
|
|
log.Error("aid(%d) epid(%d) type(%d) not exist", aid, epid, seasonType)
|
|
return
|
|
}
|
|
s.etamMutex.Lock()
|
|
s.eTam[epid] = aid
|
|
s.etamMutex.Unlock()
|
|
return
|
|
}
|
|
|
|
// 播放计数主方法
|
|
func (s *Service) countClick(ctx context.Context, msg *model.ClickMsg, i int64) (err error) {
|
|
var (
|
|
ci *model.ClickInfo
|
|
ok bool
|
|
now = time.Now().Unix()
|
|
)
|
|
if msg == nil {
|
|
log.Info("svr close s.aidMap length is %d", len(s.aidMap[i]))
|
|
for _, ci = range s.aidMap[i] {
|
|
// 反正这些视频点击数很多,不差这些,照顾小透明
|
|
if ci.GetSum() > 100 {
|
|
continue
|
|
}
|
|
s.upClick(ctx, ci)
|
|
}
|
|
return
|
|
}
|
|
idx := msg.AID % s.c.ChanNum
|
|
if atomic.LoadInt64(&s.lockedMap[idx]) == _locked {
|
|
log.Info("locking aidMap[%d] current length(%d)", idx, len(s.aidMap[idx]))
|
|
for _, ci := range s.aidMap[idx] {
|
|
if ci.GetSum() > 100 {
|
|
continue
|
|
}
|
|
s.upClick(ctx, ci)
|
|
delete(s.aidMap[idx], ci.Aid)
|
|
time.Sleep(1 * time.Millisecond)
|
|
}
|
|
atomic.StoreInt64(&s.lockedMap[idx], _unLock)
|
|
log.Info("unlocked aidMap[%d] current length(%d)", idx, len(s.aidMap[idx]))
|
|
}
|
|
if ci, ok = s.aidMap[idx][msg.AID]; !ok {
|
|
if ci, err = s.db.Click(ctx, msg.AID); err != nil {
|
|
log.Error("s.db.Click(%d) error(%v)", msg.AID, err)
|
|
return
|
|
}
|
|
if ci == nil {
|
|
if _, err = s.db.AddClick(ctx, msg.AID, 0, 0, 0, 0, 0, 0); err != nil {
|
|
log.Error("s.db.AddClick(%d) error(%v)", msg.AID, err)
|
|
return
|
|
}
|
|
ci = &model.ClickInfo{Aid: msg.AID}
|
|
}
|
|
ci.Ready(now)
|
|
s.aidMap[idx][msg.AID] = ci
|
|
}
|
|
switch msg.Plat {
|
|
case 0:
|
|
ci.Web++
|
|
case 1:
|
|
ci.H5++
|
|
case 2:
|
|
ci.Outer++
|
|
case 3:
|
|
ci.Ios++
|
|
case 4:
|
|
ci.Android++
|
|
case 5:
|
|
ci.AndroidTV++
|
|
}
|
|
if ci.Sum == 0 || now-ci.LastChangeTime > s.c.LastChangeTime {
|
|
if err = s.upClick(ctx, ci); err != nil {
|
|
log.Error("s.upClick(%v) error(%v)", ci, err)
|
|
return
|
|
}
|
|
log.Info("truly add click message(%+v)", msg)
|
|
if now-ci.LastChangeTime > s.c.ReleaseTime || ci.Aid == s.c.BnjMainAid || ci.NeedRelease() {
|
|
delete(s.aidMap[idx], msg.AID)
|
|
return
|
|
}
|
|
ci.Ready(now)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Service) upClick(c context.Context, ci *model.ClickInfo) (err error) {
|
|
if _, err = s.db.UpClick(c, ci); err != nil {
|
|
log.Error("s.db.UpClick(%+v) error(%v)", ci, err)
|
|
return
|
|
}
|
|
s.busChan <- &model.StatMsg{AID: ci.Aid, Click: int(ci.Sum + ci.GetSum())}
|
|
// 拜年祭需求 单品视频的播放数算进主视频
|
|
if _, ok := s.bnjListAidMap[ci.Aid]; ok {
|
|
bnj := &model.ClickInfo{
|
|
Aid: s.c.BnjMainAid,
|
|
Web: ci.Web,
|
|
H5: ci.H5,
|
|
Outer: ci.Outer,
|
|
Ios: ci.Ios,
|
|
Android: ci.Android,
|
|
AndroidTV: ci.AndroidTV,
|
|
}
|
|
if _, err = s.db.UpClick(c, bnj); err != nil {
|
|
log.Error("s.db.UpClick(%d) error(%v)", s.c.BnjMainAid, err)
|
|
return
|
|
}
|
|
log.Info("bnjaid(%d) Forced to increase click(%v) by relateAid(%d)", s.c.BnjMainAid, bnj, ci.Aid)
|
|
}
|
|
// 拜年祭需求 单品视频的播放数算进主视频
|
|
return
|
|
}
|
|
|
|
// SetSpecial http set special aid click
|
|
func (s *Service) SetSpecial(c context.Context, aid, num int64, tp string) (err error) {
|
|
_, err = s.db.UpSpecial(c, aid, tp, num)
|
|
return
|
|
}
|