You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
286 lines
6.9 KiB
286 lines
6.9 KiB
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 |
|
}
|
|
|