@@ -0,0 +1,150 @@
|
||||
package job
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/enum/imad"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/stderr"
|
||||
"91porn-server/models/cache/sysconfdata"
|
||||
"91porn-server/models/v/sysconfmod"
|
||||
"91porn-server/skd/skdg"
|
||||
"91porn-server/services/srv_im"
|
||||
)
|
||||
|
||||
const (
|
||||
imAdNotifyLockKey = "skd:im_ad_notify:online:lock"
|
||||
imAdNotifyLastRunKey = "skd:im_ad_notify:online:last_run"
|
||||
imAdNotifyLockTTL = 10 * time.Minute
|
||||
)
|
||||
|
||||
type imAdNotifyConfig struct {
|
||||
Enable bool
|
||||
IntervalMinutes int64
|
||||
Positions []string
|
||||
MaxUsers int
|
||||
}
|
||||
|
||||
// IMAdNotifyOnline 按 sysconf.imConfig 定时向当前 IM 在线用户透传广告刷新通知。
|
||||
func IMAdNotifyOnline() {
|
||||
if err := imAdNotifyOnline(); err != nil {
|
||||
log.Error("IMAdNotifyOnline failed", log.E(err))
|
||||
}
|
||||
}
|
||||
|
||||
func imAdNotifyOnline() error {
|
||||
conf := loadIMAdNotifyConfig()
|
||||
now := time.Now()
|
||||
lastRunAt, err := loadIMAdNotifyLastRunAt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !shouldRunIMAdNotify(conf, lastRunAt, now) {
|
||||
return nil
|
||||
}
|
||||
|
||||
acquired, err := skdg.Redis.Setnx_NewOK(imAdNotifyLockKey, 1, imAdNotifyLockTTL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !acquired {
|
||||
log.Info("IMAdNotifyOnline skipped: lock held")
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
if _, err := skdg.Redis.Del(imAdNotifyLockKey); err != nil {
|
||||
log.Warn("IMAdNotifyOnline release lock failed", log.E(err))
|
||||
}
|
||||
}()
|
||||
|
||||
lastRunAt, err = loadIMAdNotifyLastRunAt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !shouldRunIMAdNotify(conf, lastRunAt, now) {
|
||||
return nil
|
||||
}
|
||||
|
||||
resp, code, msg := srv_im.SendAdNotify(srv_im.AdNotifyReq{
|
||||
Target: "online",
|
||||
Positions: conf.Positions,
|
||||
MaxUsers: conf.MaxUsers,
|
||||
})
|
||||
if code != stderr.Success {
|
||||
return fmt.Errorf("im ad notify failed: code=%d msg=%s", code, msg)
|
||||
}
|
||||
log.Info("IMAdNotifyOnline done", log.Any("resp", resp))
|
||||
return saveIMAdNotifyLastRunAt(now)
|
||||
}
|
||||
|
||||
func loadIMAdNotifyConfig() imAdNotifyConfig {
|
||||
conf := imAdNotifyConfig{IntervalMinutes: 60, MaxUsers: 1000}
|
||||
all, err := sysconfdata.GetAllFromCache()
|
||||
if err != nil {
|
||||
log.Warn("load im sysconf failed", log.E(err))
|
||||
return conf
|
||||
}
|
||||
conf.Enable = all.GetBool(sysconfmod.VCodeIMAdEnable)
|
||||
if v := all.GetInt(sysconfmod.VCodeIMAdIntervalMinutes); v > 0 {
|
||||
conf.IntervalMinutes = v
|
||||
}
|
||||
if v := all.GetInt(sysconfmod.VCodeIMAdMaxUsers); v > 0 {
|
||||
conf.MaxUsers = int(v)
|
||||
}
|
||||
// 每个广告位独立开关,开了就加进去
|
||||
conf.Positions = collectEnabledIMAdPositions(all)
|
||||
return conf
|
||||
}
|
||||
|
||||
// collectEnabledIMAdPositions 把启用了的广告位 code 收集成列表
|
||||
func collectEnabledIMAdPositions(all sysconfmod.ConfMap) []string {
|
||||
positions := make([]string, 0, 4)
|
||||
if all.GetBool(sysconfmod.VCodeIMAdPosChatNotificationBar) {
|
||||
positions = append(positions, imad.ChatNotificationBar)
|
||||
}
|
||||
if all.GetBool(sysconfmod.VCodeIMAdPosChatFloatingGifBall) {
|
||||
positions = append(positions, imad.ChatFloatingGifBall)
|
||||
}
|
||||
if all.GetBool(sysconfmod.VCodeIMAdPosListFeedNative) {
|
||||
positions = append(positions, imad.ListFeedNative)
|
||||
}
|
||||
if all.GetBool(sysconfmod.VCodeIMAdPosListBanner) {
|
||||
positions = append(positions, imad.ListBanner)
|
||||
}
|
||||
return positions
|
||||
}
|
||||
|
||||
func shouldRunIMAdNotify(conf imAdNotifyConfig, lastRunAt time.Time, now time.Time) bool {
|
||||
if !conf.Enable || len(conf.Positions) == 0 {
|
||||
return false
|
||||
}
|
||||
if lastRunAt.IsZero() {
|
||||
return true
|
||||
}
|
||||
return !now.Before(lastRunAt.Add(normalizeIMAdNotifyInterval(conf.IntervalMinutes)))
|
||||
}
|
||||
|
||||
func normalizeIMAdNotifyInterval(intervalMinutes int64) time.Duration {
|
||||
if intervalMinutes <= 0 {
|
||||
intervalMinutes = 60
|
||||
}
|
||||
return time.Duration(intervalMinutes) * time.Minute
|
||||
}
|
||||
|
||||
func loadIMAdNotifyLastRunAt() (time.Time, error) {
|
||||
val, err := skdg.Redis.Get(imAdNotifyLastRunKey)
|
||||
if err != nil || val == nil || *val == "" {
|
||||
return time.Time{}, err
|
||||
}
|
||||
unixSec, err := strconv.ParseInt(*val, 10, 64)
|
||||
if err != nil || unixSec <= 0 {
|
||||
return time.Time{}, nil
|
||||
}
|
||||
return time.Unix(unixSec, 0), nil
|
||||
}
|
||||
|
||||
func saveIMAdNotifyLastRunAt(now time.Time) error {
|
||||
return skdg.Redis.Set(imAdNotifyLastRunKey, strconv.FormatInt(now.Unix(), 10), 0)
|
||||
}
|
||||
Reference in New Issue
Block a user