123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754 |
- package dao
- import (
- "context"
- "encoding/json"
- "fmt"
- "strconv"
- "strings"
- "time"
- v1pb "go-common/app/service/live/dao-anchor/api/grpc/v1"
- "go-common/library/cache/redis"
- "go-common/library/ecode"
- "go-common/library/log"
- )
- //实时消费缓存设计,异步落地
- const VALUE = "value"
- const DATE = "date" //是否最新消息,是为1(需要刷新到DB) 否为0(不需要刷新到DB)
- const DATE_1 = "1"
- type ListIntValueInfo struct {
- Value int64 `json:"value"`
- Time int64 `json:"time"`
- }
- //Set 设置实时数据
- func (d *Dao) Set(ctx context.Context, redisKey string, value string, timeOut int) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- if _, err = conn.Do("HMSET", redisKey, VALUE, value, DATE, DATE_1); err != nil {
- log.Error("redis_set_err:key=%s;value=%s;err=%v", redisKey, value, err)
- return
- }
- conn.Do("EXPIRE", redisKey, timeOut)
- return
- }
- //Incr 设置增加数据
- func (d *Dao) Incr(ctx context.Context, redisKey string, value int64, timeOut int) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- if err = conn.Send("HINCRBY", redisKey, VALUE, value); err != nil {
- log.Error("redis_incr_err:key=%s;value=%d;err=%v", redisKey, value, err)
- return
- }
- if err = conn.Send("HSET", redisKey, DATE, DATE_1); err != nil {
- log.Error("redis_hset_err:key=%s;date_value=%s;err=%v", redisKey, DATE_1, err)
- return
- }
- conn.Send("EXPIRE", redisKey, timeOut)
- if err = conn.Flush(); err != nil {
- log.Error("redisIncreRoomInfo conn.Flush error(%v)", err)
- return
- }
- _, err = conn.Receive()
- _, err = conn.Receive()
- _, err = conn.Receive()
- return
- }
- func (d *Dao) HGet(ctx context.Context, redisKey string) (resp int64, err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- resp, err = redis.Int64(conn.Do("HGET", redisKey, VALUE))
- if err != nil {
- log.Error("redis_incr_err:key=%s;reply=%d;err=%v", redisKey, resp, err)
- return
- }
- return
- }
- func (d *Dao) SetList(ctx context.Context, redisKey string, value string, timeOut int) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- if _, err = conn.Do("LPUSH", redisKey, value); err != nil {
- log.Error("redis_setList_error:key=%s;value=%s;err=%v", redisKey, value, err)
- return
- }
- conn.Do("EXPIRE", redisKey, timeOut)
- return
- }
- func (d *Dao) GetList(ctx context.Context, redisKey string, start int, end int) (resp []*ListIntValueInfo, err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- res, err := redis.Values(conn.Do("LRANGE", redisKey, start, end))
- if err != nil {
- log.Error("redis_getList_error:key=%s;err=%v", redisKey, err)
- return
- }
- for _, sList := range res {
- list := &ListIntValueInfo{}
- if err = json.Unmarshal(sList.([]byte), &list); err != nil {
- log.Error("GetList_json_error")
- continue
- }
- resp = append(resp, list)
- }
- return
- }
- // GetRoomRecordsCurrent return a list of records corresponding to `content`.
- func (d *Dao) GetRoomRecordsCurrent(ctx context.Context, content string, roomIds []int64) (list []int64, err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- for _, roomId := range roomIds {
- key := d.SRoomRecordCurrent(content, roomId)
- if err = conn.Send("HGET", key.RedisKey, VALUE); err != nil {
- log.Error("GetRoomRecordsCurrent conn.Send(HGET, %s, %s) error(%v)", key.RedisKey, VALUE, err)
- return nil, err
- }
- }
- if err = conn.Flush(); err != nil {
- log.Error("GetRoomRecordsCurrent conn.Flush error(%v)", err)
- return nil, err
- }
- for i := 0; i < len(roomIds); i++ {
- var data int64
- if data, err = redis.Int64(conn.Receive()); err != nil {
- if err != redis.ErrNil {
- log.Error("GetRoomRecordsCurrent conn.Receive() %d error(%v)", i, err)
- return nil, err
- }
- }
- list = append(list, data)
- }
- return
- }
- func (d *Dao) DelRoomRecordsCurrent(ctx context.Context, content string, roomIds []int64) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- args := make([]interface{}, len(roomIds))
- for i, roomId := range roomIds {
- args[i] = d.SRoomRecordCurrent(content, roomId)
- }
- if _, err = conn.Do("DEL", args...); err != nil {
- log.Error("DelRoomRecordsCurrent_del_error:%v;roomIds=%v", err, roomIds)
- return
- }
- return
- }
- func (d *Dao) SetRoomRecordsList(ctx context.Context, roomIds []int64, keys map[int64]interface{}, values map[int64]string) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- for _, roomId := range roomIds {
- keyInfo := keys[roomId].(*redisKeyResp)
- value := values[roomId]
- if err = conn.Send("LPUSH", keyInfo.RedisKey, value); err != nil {
- log.Error("SetRoomRecordsList conn.Send(LPUSH, %s, %s) error(%v)", keyInfo.RedisKey, value, err)
- return err
- }
- if err = conn.Send("EXPIRE", keyInfo.RedisKey, keyInfo.TimeOut); err != nil {
- log.Error("SetRoomRecordsList conn.Send(EXPIRE, %s, %d) error(%v)", keyInfo.RedisKey, keyInfo.TimeOut, err)
- return err
- }
- }
- if err = conn.Flush(); err != nil {
- log.Error("SetRoomRecordsList conn.Flush() error(%v)", err)
- return err
- }
- for range roomIds {
- conn.Receive()
- conn.Receive()
- }
- return
- }
- // GetRoomLiveRecordsRange can partially succeed, and in this case, err is still nil.
- func (d *Dao) GetRoomLiveRecordsRange(ctx context.Context, content string, roomIds []int64, liveTime int64, start, end int) (resp map[int64][]*ListIntValueInfo, err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- okRoomIds := make([]int64, 0, len(roomIds))
- for _, roomId := range roomIds {
- keyInfo := d.LRoomLiveRecordList(content, roomId, liveTime)
- if err = conn.Send("LRANGE", keyInfo.RedisKey, start, end); err != nil {
- log.Error("GetRoomLiveRecordsRange conn.Send(LRANGE, %s, %d, %d) error(%v)", keyInfo.RedisKey, start, end, err)
- continue
- }
- okRoomIds = append(okRoomIds, roomId)
- }
- if err = conn.Flush(); err != nil {
- log.Error("GetRoomLiveRecordsRange conn.Flush() error(%v)", err)
- return nil, err
- }
- resp = make(map[int64][]*ListIntValueInfo)
- for i := 0; i < len(okRoomIds); i++ {
- values, err := redis.Values(conn.Receive())
- if err != nil {
- log.Error("GetRoomLiveRecordsRange redis.Values(conn.Receive()) error(%v)", err)
- continue
- }
- roomId := okRoomIds[i]
- for _, info := range values {
- valueInfo := &ListIntValueInfo{}
- if err = json.Unmarshal(info.([]byte), &valueInfo); err != nil {
- log.Error("GetRoomLiveRecordsRange json unmarshall error(%v)", err)
- continue
- }
- resp[roomId] = append(resp[roomId], valueInfo)
- }
- }
- return resp, nil
- }
- const (
- _roomInfoKey = "room_info_v3:%d"
- _anchorInfoKey = "anchor_info:%d"
- _onlineListKey = "online_list_v3:%d"
- _tagListKey = "tag_list_v3:%d"
- _onlineListAllArea = 0
- )
- var (
- _allRoomInfoFields = []string{"uid", "title", "cover", "tags", "background", "description", "live_start_time", "live_status", "live_screen_type", "live_type", "lock_status", "lock_time", "hidden_time", "hidden_status", "area_id", "parent_area_id", "anchor_profile_type", "anchor_round_switch", "anchor_record_switch", "anchor_exp", "popularity_count", "keyframe"}
- )
- func (d *Dao) filterOutTagList(fields []string) (resp []string, needTagList bool) {
- resp = make([]string, 0, len(fields))
- for _, f := range fields {
- if f == "tag_list" {
- needTagList = true
- } else {
- resp = append(resp, f)
- }
- }
- return
- }
- func (d *Dao) redisGetRoomInfo(ctx context.Context, roomID int64, fields []string) (data *v1pb.RoomData, err error) {
- if len(fields) <= 0 {
- return
- }
- conn := d.redis.Get(ctx)
- defer conn.Close()
- roomKey := fmt.Sprintf(_roomInfoKey, roomID)
- ok, err := redis.Bool(conn.Do("EXPIRE", roomKey, d.c.Common.ExpireTime))
- if err != nil && err != redis.ErrNil {
- log.Error("redisGetRoomInfo conn.Do(EXPIRE, %s) error(%v)", roomKey, err)
- return
- }
- if !ok {
- err = ecode.RoomNotFound
- return
- }
- for _, f := range fields {
- if f == "room_id" {
- continue
- }
- if err = conn.Send("HGET", roomKey, f); err != nil {
- log.Error("redisGetRoomInfo conn.Send(HGET, %s, %s) error(%v)", roomKey, f, err)
- return
- }
- }
- if err = conn.Flush(); err != nil {
- log.Error("redisGetRoomInfo conn.Flush error(%v)", err)
- return
- }
- data = &v1pb.RoomData{
- RoomId: roomID,
- AnchorLevel: new(v1pb.AnchorLevel),
- }
- for _, f := range fields {
- if f == "room_id" {
- continue
- }
- reply, err := conn.Receive()
- if e, ok := err.(*redis.Error); ok && strings.Index(e.Error(), "WRONGTYPE") != -1 {
- return data, err
- }
- switch f {
- case "uid":
- data.Uid, err = redis.Int64(reply, err)
- case "title":
- data.Title, err = redis.String(reply, err)
- case "cover":
- data.Cover, err = redis.String(reply, err)
- case "tags":
- data.Tags, err = redis.String(reply, err)
- case "background":
- data.Background, err = redis.String(reply, err)
- case "description":
- data.Description, err = redis.String(reply, err)
- case "live_start_time":
- data.LiveStartTime, err = redis.Int64(reply, err)
- case "live_status":
- data.LiveStatus, err = redis.Int64(reply, err)
- case "live_screen_type":
- data.LiveScreenType, err = redis.Int64(reply, err)
- case "live_type":
- data.LiveType, err = redis.Int64(reply, err)
- case "lock_status":
- data.LockStatus, err = redis.Int64(reply, err)
- case "lock_time":
- data.LockTime, err = redis.Int64(reply, err)
- case "hidden_time":
- data.HiddenTime, err = redis.Int64(reply, err)
- case "hidden_status":
- data.HiddenStatus, err = redis.Int64(reply, err)
- case "area_id":
- data.AreaId, err = redis.Int64(reply, err)
- case "parent_area_id":
- data.ParentAreaId, err = redis.Int64(reply, err)
- case "anchor_san":
- data.AnchorSan, err = redis.Int64(reply, err)
- case "anchor_profile_type":
- data.AnchorProfileType, err = redis.Int64(reply, err)
- case "anchor_round_switch":
- data.AnchorRoundSwitch, err = redis.Int64(reply, err)
- case "anchor_record_switch":
- data.AnchorRecordSwitch, err = redis.Int64(reply, err)
- case "anchor_exp":
- data.AnchorLevel.Score, err = redis.Int64(reply, err)
- case "popularity_count":
- data.PopularityCount, err = redis.Int64(reply, err)
- case "keyframe":
- data.Keyframe, err = redis.String(reply, err)
- default:
- log.Error("redisGetRoomInfo unsupported field(%v), roomID(%d)", f, roomID)
- err = ecode.InvalidParam
- return nil, err
- }
- if err != nil {
- log.Warn("redisGetRoomInfo conn.Receive() field(%v), error(%v)", f, err)
- return nil, err
- }
- }
- return
- }
- func (d *Dao) redisSetRoomInfo(ctx context.Context, roomID int64, fields []string, data *v1pb.RoomData, fastfail bool) (err error) {
- if len(fields) <= 0 {
- return
- }
- conn := d.redis.Get(ctx)
- defer conn.Close()
- roomKey := fmt.Sprintf(_roomInfoKey, roomID)
- ok, err := redis.Bool(conn.Do("EXPIRE", roomKey, d.c.Common.ExpireTime))
- if err != nil && err != redis.ErrNil {
- log.Error("redisSetRoomInfo conn.Do(EXPIRE, %s) error(%v)", roomKey, err)
- return
- }
- if !ok && fastfail {
- return
- }
- args := make([]interface{}, len(fields)*2+1)
- args[0] = roomKey
- for i, f := range fields {
- var v interface{}
- switch f {
- case "roomid":
- v = data.RoomId
- case "uid":
- v = data.Uid
- case "title":
- v = data.Title
- case "cover":
- v = data.Cover
- case "tags":
- v = data.Tags
- case "background":
- v = data.Background
- case "description":
- v = data.Description
- case "live_start_time":
- v = data.LiveStartTime
- case "live_status":
- v = data.LiveStatus
- case "live_screen_type":
- v = data.LiveScreenType
- case "live_type":
- v = data.LiveType
- case "lock_status":
- v = data.LockStatus
- case "lock_time":
- v = data.LockTime
- case "hidden_time":
- v = data.HiddenTime
- case "hidden_status":
- v = data.HiddenStatus
- case "area_id":
- v = data.AreaId
- case "parent_area_id":
- v = data.ParentAreaId
- case "anchor_san":
- v = data.AnchorSan
- case "anchor_profile_type":
- v = data.AnchorProfileType
- case "anchor_round_switch":
- v = data.AnchorRoundSwitch
- case "anchor_record_switch":
- v = data.AnchorRecordSwitch
- case "anchor_exp":
- v = data.AnchorRecordSwitch
- case "popularity_count":
- v = data.PopularityCount
- case "keyframe":
- v = data.Keyframe
- default:
- log.Error("redisSetRoomInfo unsupported field(%v), roomID(%d)", f, roomID)
- return ecode.InvalidParam
- }
- args[i*2+1] = f
- args[i*2+2] = v
- }
- if _, err = conn.Do("HMSET", args...); err != nil {
- log.Error("redisSetRoomInfo conn.Do(HMSET, %v) error(%v)", args, err)
- return
- }
- return
- }
- func (d *Dao) redisIncreRoomInfo(ctx context.Context, roomID int64, fields []string, data *v1pb.RoomData) (err error) {
- if len(fields) <= 0 {
- return
- }
- conn := d.redis.Get(ctx)
- defer conn.Close()
- roomKey := fmt.Sprintf(_roomInfoKey, roomID)
- ok, err := redis.Bool(conn.Do("EXPIRE", roomKey, d.c.Common.ExpireTime))
- if err != nil && err != redis.ErrNil {
- log.Error("redisIncreRoomInfo conn.Do(EXPIRE, %s) error(%v)", roomKey, err)
- return
- }
- // fast fail if key not exists
- if !ok {
- return
- }
- for _, f := range fields {
- var v int64
- switch f {
- case "anchor_san":
- v = data.AnchorSan
- case "anchor_exp":
- v = data.AnchorRecordSwitch
- case "popularity_count":
- v = data.PopularityCount
- default:
- log.Error("redisIncreRoomInfo unsupported field(%v), roomID(%d)", f, roomID)
- return ecode.InvalidParam
- }
- if err = conn.Send("HINCRBY", roomKey, f, v); err != nil {
- log.Error("redisIncreRoomInfo conn.Send(HINCRBY, %s, %s, %d) error(%v)", roomKey, f, v, err)
- return
- }
- }
- if err = conn.Flush(); err != nil {
- log.Error("redisIncreRoomInfo conn.Flush error(%v)", err)
- return
- }
- for _, f := range fields {
- _, err = conn.Receive()
- if err != nil && err != redis.ErrNil {
- log.Error("redisIncreRoomInfo conn.Receive() field(%v), error(%v)", f, err)
- return
- }
- }
- return
- }
- func (d *Dao) redisGetOnlineList(ctx context.Context, areaID int64) (list []int64, err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- key := fmt.Sprintf(_onlineListKey, areaID)
- ok, err := redis.Bool(conn.Do("EXPIRE", key, d.c.Common.ExpireTime))
- if err != nil && err != redis.ErrNil {
- log.Error("redisGetOnlineList conn.Do(EXPIRE, %s) error(%v)", key, err)
- return
- }
- if !ok {
- // 不存在或者在播列表为空都会重新去DB获取
- return
- }
- list = make([]int64, 0)
- roomids, err := redis.Strings(conn.Do("SMEMBERS", key))
- if err != nil && err != redis.ErrNil {
- if e, ok := err.(*redis.Error); ok && strings.Index(e.Error(), "WRONGTYPE") == -1 {
- log.Error("redisGetOnlineList conn.Do(SMEMBERS, %s) error(%v)", key, err)
- return
- }
- return list, nil
- }
- for _, id := range roomids {
- roomid, err := strconv.ParseInt(id, 10, 64)
- if err != nil {
- log.Warn("redisGetOnlineList ParseInt(%d) error(%v)", roomid, err)
- return nil, err
- }
- list = append(list, roomid)
- }
- return
- }
- func (d *Dao) redisSetOnlineList(ctx context.Context, areaID int64, list []int64) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- key := fmt.Sprintf(_onlineListKey, areaID)
- if len(list) <= 0 {
- // 设置哨兵
- if _, err = conn.Do("SETEX", key, d.c.Common.ExpireTime, "emptylist"); err != nil {
- log.Error("redisSetOnlineList conn.Do(SETEX, %s, %v) error(%v)", key, list, err)
- }
- return
- }
- if _, err = conn.Do("DEL", key); err != nil && err != redis.ErrNil {
- log.Error("redisSetOnlineList conn.Do(DEL, %s) error(%v)", key, err)
- return
- }
- args := make([]interface{}, len(list)+1)
- args[0] = key
- for i, id := range list {
- args[i+1] = id
- }
- if _, err = conn.Do("SADD", args...); err != nil {
- log.Error("redisSetOnlineList conn.Do(SADD, %s, %v) error(%v)", key, list, err)
- return
- }
- return
- }
- func (d *Dao) redisAddOnlineList(ctx context.Context, areaID int64, roomID int64) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- key := fmt.Sprintf(_onlineListKey, areaID)
- typ, err := redis.String(conn.Do("TYPE", key))
- if err != nil && err != redis.ErrNil {
- log.Error("redisAddOnlineList conn.Do(TYPE, %s) error(%v)", key, err)
- return
- }
- if strings.ToLower(typ) == "none" {
- // 不存在就不处理
- return
- } else if strings.ToLower(typ) != "set" {
- if _, err = conn.Do("DEL", key); err != nil && err != redis.ErrNil {
- log.Error("redisAddOnlineList conn.Do(DEL, %s) error(%v)", key, err)
- return
- }
- }
- if _, err = conn.Do("SADD", key, roomID); err != nil {
- log.Error("redisAddOnlineList conn.Do(SADD, %s, %d) error(%v)", key, roomID, err)
- return
- }
- return
- }
- func (d *Dao) redisDelOnlineList(ctx context.Context, areaID int64, roomID int64) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- key := fmt.Sprintf(_onlineListKey, areaID)
- typ, err := redis.String(conn.Do("TYPE", key))
- if err != nil && err != redis.ErrNil {
- log.Error("redisDelOnlineList conn.Do(TYPE, %s) error(%v)", key, err)
- return
- }
- if strings.ToLower(typ) != "set" {
- // 不存在就不处理
- return
- }
- if _, err = conn.Do("SREM", key, roomID); err != nil {
- log.Error("redisDelOnlineList conn.Do(SADD, %s, %d) error(%v)", key, roomID, err)
- return
- }
- return
- }
- func (d *Dao) redisGetTagList(ctx context.Context, roomID int64) (list []*v1pb.TagData, err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- key := fmt.Sprintf(_tagListKey, roomID)
- ok, err := redis.Bool(conn.Do("EXPIRE", key, d.c.Common.ExpireTime))
- if err != nil && err != redis.ErrNil {
- log.Error("redisGetTagList conn.Do(EXPIRE, %s) error(%v)", key, err)
- return nil, err
- }
- if !ok {
- err = ecode.RoomNotFound
- return
- }
- list = make([]*v1pb.TagData, 0)
- tags, err := redis.Strings(conn.Do("SMEMBERS", key))
- if err != nil && err != redis.ErrNil {
- if e, ok := err.(*redis.Error); ok && strings.Index(e.Error(), "WRONGTYPE") == -1 {
- log.Error("redisGetTagList conn.Do(SMEMBERS, %s) error(%v)", key, err)
- return
- }
- return list, nil
- }
- for _, tag := range tags {
- seg := strings.Split(tag, ":")
- if len(seg) < 5 {
- log.Error("redisGetTagList Split(%s) error(%v)", tag, err)
- return nil, err
- }
- data := &v1pb.TagData{
- TagExt: strings.Join(seg[4:], ":"),
- }
- data.TagExpireAt, _ = strconv.ParseInt(seg[3], 10, 64)
- if data.TagExpireAt > time.Now().Unix() {
- data.TagId, _ = strconv.ParseInt(seg[0], 10, 64)
- data.TagSubId, _ = strconv.ParseInt(seg[1], 10, 64)
- data.TagValue, _ = strconv.ParseInt(seg[2], 10, 64)
- list = append(list, data)
- }
- }
- return
- }
- func (d *Dao) redisAddTag(ctx context.Context, roomID int64, tag *v1pb.TagData) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- key := fmt.Sprintf(_tagListKey, roomID)
- typ, err := redis.String(conn.Do("TYPE", key))
- if err != nil && err != redis.ErrNil {
- log.Error("redisAddTag conn.Do(TYPE, %s) error(%v)", key, err)
- return
- }
- if strings.ToLower(typ) == "none" {
- // 不存在就不处理
- return
- } else if strings.ToLower(typ) != "set" {
- if _, err = conn.Do("DEL", key); err != nil && err != redis.ErrNil {
- log.Error("redisAddTag conn.Do(DEL, %s) error(%v)", key, err)
- return
- }
- }
- tagVal := fmt.Sprintf("%d:%d:%d:%d:%s", tag.TagId, tag.TagSubId, tag.TagValue, tag.TagExpireAt, tag.TagExt)
- if _, err = conn.Do("SADD", key, tagVal); err != nil {
- log.Error("redisAddTag conn.Do(SADD, %s, %s) error(%v)", key, tagVal, err)
- return
- }
- return
- }
- func (d *Dao) redisSetTagList(ctx context.Context, roomID int64, list []*v1pb.TagData) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- key := fmt.Sprintf(_tagListKey, roomID)
- if len(list) <= 0 {
- // 设置哨兵
- if _, err = conn.Do("SETEX", key, d.c.Common.ExpireTime, "emptylist"); err != nil {
- log.Error("redisSetTagList conn.Do(SETEX, %s, %v) error(%v)", key, list, err)
- }
- return
- }
- if _, err = conn.Do("DEL", key); err != nil && err != redis.ErrNil {
- log.Error("redisSetTagList conn.Do(DEL, %s) error(%v)", key, err)
- return
- }
- args := make([]interface{}, len(list)+1)
- args[0] = key
- for i, tag := range list {
- args[i+1] = fmt.Sprintf("%d:%d:%d:%d:%s", tag.TagId, tag.TagSubId, tag.TagValue, tag.TagExpireAt, tag.TagExt)
- }
- if _, err = conn.Do("SADD", args...); err != nil {
- log.Error("redisSetTagList conn.Do(SADD, %s, %v) error(%v)", key, list, err)
- return
- }
- return
- }
|