287 lines
6.9 KiB
Go
287 lines
6.9 KiB
Go
package pendant
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
|
|
"encoding/json"
|
|
|
|
"go-common/app/service/main/usersuit/model"
|
|
"go-common/library/cache/redis"
|
|
"go-common/library/log"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
_pendantPKG = "pkg_" // key of
|
|
_pendantEquip = "pe_"
|
|
)
|
|
|
|
func keyEquip(mid int64) string {
|
|
return _pendantEquip + strconv.FormatInt(mid, 10)
|
|
}
|
|
|
|
// encode
|
|
func (d *Dao) encode(mid, pid, expires, tp int64, status, isVIP int32, pendant *model.Pendant) (res []byte, err error) {
|
|
ft := &model.PendantPackage{Mid: mid, Pid: pid, Expires: expires, Type: tp, Status: status, IsVIP: isVIP, Pendant: pendant}
|
|
return json.Marshal(ft)
|
|
}
|
|
|
|
// decode
|
|
func (d *Dao) decode(src []byte, v *model.PendantPackage) (err error) {
|
|
return json.Unmarshal(src, v)
|
|
}
|
|
|
|
// AddPKGCache set package cache.
|
|
func (d *Dao) AddPKGCache(c context.Context, mid int64, info []*model.PendantPackage) (err error) {
|
|
var (
|
|
key = _pendantPKG + strconv.FormatInt(mid, 10)
|
|
args = redis.Args{}.Add(key)
|
|
)
|
|
for i := 0; i < len(info); i++ {
|
|
var ef []byte
|
|
if ef, err = d.encode(info[i].Mid, info[i].Pid, info[i].Expires, info[i].Type, info[i].Status, info[i].IsVIP, info[i].Pendant); err != nil {
|
|
return
|
|
}
|
|
args = args.Add(i, ef)
|
|
}
|
|
conn := d.redis.Get(c)
|
|
defer conn.Close()
|
|
if err = conn.Send("DEL", key); err != nil {
|
|
log.Error("conn.Send(DEL, %s) error(%v)", key, err)
|
|
return
|
|
}
|
|
if err = conn.Send("HMSET", args...); err != nil {
|
|
log.Error("conn.Send(HMSET, %s) error(%v)", key, err)
|
|
return
|
|
}
|
|
|
|
if err = conn.Send("EXPIRE", key, d.pendantExpire); err != nil {
|
|
log.Error("conn.Send(EXPIRE, %s) error(%v)", key, err)
|
|
return
|
|
}
|
|
if err = conn.Flush(); err != nil {
|
|
log.Error("conn.Flush() error(%v)", err)
|
|
return
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
if _, err = conn.Receive(); err != nil {
|
|
log.Error("conn.Receive() %d error(%v)", i+1, err)
|
|
break
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// PKGCache get package cache.
|
|
func (d *Dao) PKGCache(c context.Context, mid int64) (info []*model.PendantPackage, err error) {
|
|
var (
|
|
key = _pendantPKG + strconv.FormatInt(mid, 10)
|
|
tmp = make(map[string]string, len(info))
|
|
)
|
|
conn := d.redis.Get(c)
|
|
defer conn.Close()
|
|
if tmp, err = redis.StringMap(conn.Do("HGETALL", key)); err != nil {
|
|
return
|
|
}
|
|
if err == nil && len(tmp) > 0 {
|
|
for i := 0; i < len(tmp); i++ {
|
|
s := strconv.FormatInt(int64(i), 10)
|
|
vf := &model.PendantPackage{}
|
|
vf.Pendant = &model.Pendant{}
|
|
if err = d.decode([]byte(tmp[s]), vf); err != nil {
|
|
return
|
|
}
|
|
info = append(info, &model.PendantPackage{
|
|
Mid: vf.Mid,
|
|
Pid: vf.Pid,
|
|
Expires: vf.Expires,
|
|
Type: vf.Type,
|
|
Status: vf.Status,
|
|
IsVIP: vf.IsVIP,
|
|
Pendant: vf.Pendant,
|
|
})
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// DelPKGCache del package cache
|
|
func (d *Dao) DelPKGCache(c context.Context, mid int64) (err error) {
|
|
key := _pendantPKG + strconv.FormatInt(mid, 10)
|
|
conn := d.redis.Get(c)
|
|
defer conn.Close()
|
|
if err = conn.Send("DEL", key); err != nil {
|
|
log.Error("conn.Send(DEL, %s) error(%v)", key, err)
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// equipCache return pendant info cache
|
|
func (d *Dao) equipCache(c context.Context, mid int64) (info *model.PendantEquip, err error) {
|
|
var (
|
|
item []byte
|
|
conn = d.redis.Get(c)
|
|
)
|
|
defer conn.Close()
|
|
if item, err = redis.Bytes(conn.Do("GET", keyEquip(mid))); err != nil {
|
|
if err == redis.ErrNil {
|
|
err = nil
|
|
}
|
|
return
|
|
}
|
|
if err = json.Unmarshal(item, &info); err != nil {
|
|
log.Error("json.Unmarshal(%v) err(%v)", item, err)
|
|
}
|
|
return
|
|
}
|
|
|
|
// equipsCache obtain equips from redis .
|
|
func (d *Dao) equipsCache(c context.Context, mids []int64) (map[int64]*model.PendantEquip, []int64, error) {
|
|
var (
|
|
err error
|
|
bss [][]byte
|
|
key string
|
|
args = redis.Args{}
|
|
conn = d.redis.Get(c)
|
|
)
|
|
|
|
for _, v := range mids {
|
|
key = keyEquip(v)
|
|
args = args.Add(key)
|
|
}
|
|
defer conn.Close()
|
|
if bss, err = redis.ByteSlices(conn.Do("MGET", args...)); err != nil {
|
|
if err == redis.ErrNil {
|
|
return nil, nil, nil
|
|
}
|
|
log.Error("Failed mget equip: keys: %+v: %+v", args, err)
|
|
return nil, nil, err
|
|
}
|
|
info := make(map[int64]*model.PendantEquip, len(mids))
|
|
for _, bs := range bss {
|
|
if bs == nil {
|
|
continue
|
|
}
|
|
pe := &model.PendantEquip{}
|
|
if err = json.Unmarshal(bs, pe); err != nil {
|
|
log.Error("json.Unmarshal(%s) error(%v)", string(bs), err)
|
|
err = nil
|
|
continue
|
|
}
|
|
info[pe.Mid] = pe
|
|
}
|
|
missed := make([]int64, 0, len(mids))
|
|
for _, mid := range mids {
|
|
if _, ok := info[mid]; !ok {
|
|
missed = append(missed, mid)
|
|
}
|
|
}
|
|
return info, missed, nil
|
|
}
|
|
|
|
// AddEquipCache set pendant info cache
|
|
func (d *Dao) AddEquipCache(c context.Context, mid int64, info *model.PendantEquip) (err error) {
|
|
var (
|
|
key = keyEquip(mid)
|
|
values []byte
|
|
conn = d.redis.Get(c)
|
|
)
|
|
defer conn.Close()
|
|
if values, err = json.Marshal(info); err != nil {
|
|
return
|
|
}
|
|
if err = conn.Send("SET", keyEquip(mid), values); err != nil {
|
|
log.Error("conn.Send(SET, %s, %d) error(%v)", key, values, err)
|
|
return
|
|
}
|
|
if err = conn.Send("EXPIRE", key, d.pendantExpire); err != nil {
|
|
log.Error("conn.Send(Expire, %s, %d) error(%v)", key, d.pendantExpire, err)
|
|
return
|
|
}
|
|
if err = conn.Flush(); err != nil {
|
|
err = errors.Wrap(err, "conn.Send Flush")
|
|
return
|
|
}
|
|
for i := 0; i < 2; i++ {
|
|
if _, err = conn.Receive(); err != nil {
|
|
err = errors.Wrap(err, "conn.Send conn.Receive()")
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// AddEquipsCache mset equips info to caache .
|
|
func (d *Dao) AddEquipsCache(c context.Context, equips map[int64]*model.PendantEquip) (err error) {
|
|
var (
|
|
bs []byte
|
|
key string
|
|
keys []string
|
|
argsMid = redis.Args{}
|
|
conn = d.redis.Get(c)
|
|
)
|
|
defer conn.Close()
|
|
for _, v := range equips {
|
|
if bs, err = json.Marshal(v); err != nil {
|
|
log.Error("json.Marshal err(%v)", err)
|
|
continue
|
|
}
|
|
key = keyEquip(v.Mid)
|
|
keys = append(keys, key)
|
|
argsMid = argsMid.Add(key).Add(string(bs))
|
|
}
|
|
if err = conn.Send("MSET", argsMid...); err != nil {
|
|
err = errors.Wrap(err, "conn.Send(MSET) error")
|
|
return
|
|
}
|
|
count := 1
|
|
for _, v := range keys {
|
|
count++
|
|
if err = conn.Send("EXPIRE", v, d.pendantExpire); err != nil {
|
|
err = errors.Wrap(err, "conn.Send error")
|
|
return
|
|
}
|
|
}
|
|
if err = conn.Flush(); err != nil {
|
|
err = errors.Wrap(err, "conn.Send Flush")
|
|
return
|
|
}
|
|
for i := 0; i < count; i++ {
|
|
if _, err = conn.Receive(); err != nil {
|
|
err = errors.Wrap(err, "conn.Send conn.Receive()")
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// DelEquipCache set pendant info cache
|
|
func (d *Dao) DelEquipCache(c context.Context, mid int64) (err error) {
|
|
key := keyEquip(mid)
|
|
conn := d.redis.Get(c)
|
|
defer conn.Close()
|
|
if _, err = conn.Do("DEL", key); err != nil {
|
|
log.Error("conn.Do(DEL, %s) error(%v)", key, err)
|
|
}
|
|
return
|
|
}
|
|
|
|
// DelEquipsCache del batch equip cache .
|
|
func (d *Dao) DelEquipsCache(c context.Context, mids []int64) (err error) {
|
|
var (
|
|
args = redis.Args{}
|
|
conn = d.redis.Get(c)
|
|
)
|
|
defer conn.Close()
|
|
for _, v := range mids {
|
|
args = args.Add(keyEquip(v))
|
|
}
|
|
if _, err = conn.Do("DEL", args...); err != nil {
|
|
log.Error("conn.Do(DEL, %s) error(%v)", args, err)
|
|
}
|
|
return
|
|
}
|