123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- 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
- }
|