-
Notifications
You must be signed in to change notification settings - Fork 0
/
click.go
201 lines (194 loc) · 5.59 KB
/
click.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
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
}