153 lines
4.2 KiB
Go
153 lines
4.2 KiB
Go
package exp
|
|
|
|
import (
|
|
"context"
|
|
expModel "go-common/app/service/live/xuser/model/exp"
|
|
gmc "go-common/library/cache/memcache"
|
|
"go-common/library/log"
|
|
"go-common/library/stat/prom"
|
|
"go-common/library/sync/errgroup"
|
|
"math/rand"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// redis cache
|
|
const (
|
|
_prefixExp = "json_e_" // 用户经验cache key,json协议
|
|
_emptyExpire = 20 * 24 * 3600
|
|
_errorMcLogPrefix = "xuser.exp.dao.memcache"
|
|
_promGetSuccess = "xuser_exp_mc:获取用户经验cache成功"
|
|
_promDelSuccess = "xuser_exp_mc:成功删除用户经验cache"
|
|
_promDelErr = "xuser_exp_mc:删除用户经验cache失败"
|
|
_promGetErr = "xuser_exp_mc:批量获取用户经验key失败"
|
|
_promScanErr = "xuser_exp_mc:解析用户经验key失败"
|
|
// _recExpire = 5 * 24 * 3600
|
|
)
|
|
|
|
var (
|
|
errorsCount = prom.BusinessErrCount
|
|
infosCount = prom.BusinessInfoCount
|
|
cacheHitCount = prom.CacheHit
|
|
cacheMissCount = prom.CacheMiss
|
|
)
|
|
|
|
// PromError prometheus error count.
|
|
func PromError(name string) {
|
|
errorsCount.Incr(name)
|
|
}
|
|
|
|
// PromInfo prometheus info count.
|
|
func PromInfo(name string) {
|
|
infosCount.Incr(name)
|
|
}
|
|
|
|
// PromCacheHit prometheus cache hit count.
|
|
func PromCacheHit(name string) {
|
|
cacheHitCount.Incr(name)
|
|
}
|
|
|
|
// PromCacheMiss prometheus cache hit count.
|
|
func PromCacheMiss(name string) {
|
|
cacheMissCount.Incr(name)
|
|
}
|
|
|
|
func expKey(mid int64) string {
|
|
return _prefixExp + strconv.FormatInt(mid, 10)
|
|
}
|
|
|
|
// SetExpListCache 批量设置用户经验cache
|
|
func (d *Dao) SetExpListCache(c context.Context, expList map[int64]*expModel.LevelInfo) (err error) {
|
|
return d.setExpListCache(c, expList)
|
|
}
|
|
|
|
// DelExpFromMemCache 删除获取用户经验cache,不支持批量
|
|
func (d *Dao) DelExpFromMemCache(c context.Context, mid int64) (err error) {
|
|
return d.delExpFromMemCache(c, expKey(mid))
|
|
}
|
|
|
|
// GetExpFromMemCache 对外接口
|
|
func (d *Dao) GetExpFromMemCache(ctx context.Context, mids []int64) (expList map[int64]*expModel.LevelInfo, missedUids []int64, err error) {
|
|
return d.getExpFromMemCache(ctx, mids)
|
|
}
|
|
|
|
// getExpFromMemCache 批量获取用户经验cache
|
|
func (d *Dao) getExpFromMemCache(ctx context.Context, mids []int64) (expList map[int64]*expModel.LevelInfo, arrayMissedUids []int64, err error) {
|
|
var expKeys []string
|
|
expList = make(map[int64]*expModel.LevelInfo)
|
|
mapMissedUids := make(map[int64]bool)
|
|
arrayMissedUids = make([]int64, 0)
|
|
for _, uid := range mids {
|
|
expKeys = append(expKeys, expKey(uid))
|
|
mapMissedUids[uid] = true
|
|
}
|
|
group := errgroup.Group{}
|
|
group.Go(func() error {
|
|
conn := d.memcache.Get(context.TODO())
|
|
defer conn.Close()
|
|
resp, err := conn.GetMulti(expKeys)
|
|
if err != nil {
|
|
PromError(_promGetErr)
|
|
log.Error(_errorMcLogPrefix+"|conn.Gets(%v) error(%v)", expKeys, err)
|
|
return nil
|
|
}
|
|
// miss uids
|
|
for _, item := range resp {
|
|
element := &expModel.LevelInfo{}
|
|
if err = conn.Scan(item, &element); err != nil {
|
|
PromError(_promScanErr)
|
|
log.Error(_errorMcLogPrefix+"|item.Scan(%s) error(%v)", item.Value, err)
|
|
return err
|
|
}
|
|
expList[element.UID] = element
|
|
mapMissedUids[element.UID] = false
|
|
}
|
|
return nil
|
|
})
|
|
group.Wait()
|
|
for k, v := range mapMissedUids {
|
|
if v {
|
|
arrayMissedUids = append(arrayMissedUids, k)
|
|
}
|
|
|
|
}
|
|
PromInfo(_promGetSuccess)
|
|
return
|
|
}
|
|
|
|
func (d *Dao) delExpFromMemCache(ctx context.Context, key string) (err error) {
|
|
conn := d.memcache.Get(ctx)
|
|
if err = conn.Delete(key); err != nil {
|
|
if err == gmc.ErrNotFound {
|
|
err = nil
|
|
} else {
|
|
log.Error(_errorMcLogPrefix+"|Delete(%s) error(%v)", key, err)
|
|
PromError(_promDelErr)
|
|
}
|
|
}
|
|
PromInfo(_promDelSuccess)
|
|
conn.Close()
|
|
return
|
|
}
|
|
|
|
func (d *Dao) setExpListCache(ctx context.Context, expList map[int64]*expModel.LevelInfo) (err error) {
|
|
expire := d.getExpire()
|
|
rand.Seed(time.Now().UnixNano())
|
|
expire = expire + rand.Int31n(3600)
|
|
conn := d.memcache.Get(context.TODO())
|
|
defer conn.Close()
|
|
for _, v := range expList {
|
|
item := &gmc.Item{Key: expKey(v.UID),
|
|
Object: &expModel.LevelInfo{UID: v.UID, UserLevel: v.UserLevel, AnchorLevel: v.AnchorLevel, CTime: v.CTime, MTime: v.MTime},
|
|
Expiration: expire, Flags: gmc.FlagJSON}
|
|
err := conn.Set(item)
|
|
if err != nil {
|
|
PromError("mc:设置上报")
|
|
log.Error(_errorMcLogPrefix+"|conn.Set(%v) error(%v)", expKey(v.UID), err)
|
|
continue
|
|
}
|
|
}
|
|
return
|
|
|
|
}
|