user_likes_redis.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package dao
  2. import (
  3. "context"
  4. "fmt"
  5. pb "go-common/app/service/main/thumbup/api"
  6. "go-common/app/service/main/thumbup/model"
  7. "go-common/library/cache/redis"
  8. "go-common/library/log"
  9. "go-common/library/stat/prom"
  10. xtime "go-common/library/time"
  11. pkgerr "github.com/pkg/errors"
  12. )
  13. func userLikesKey(businessID, mid int64, state int8) string {
  14. return fmt.Sprintf("u_m_%d_b_%d_%d", mid, businessID, state)
  15. }
  16. // CacheUserLikeList .
  17. func (d *Dao) CacheUserLikeList(c context.Context, mid, businessID int64, state int8, start, end int) (res []*model.ItemLikeRecord, err error) {
  18. conn := d.redis.Get(c)
  19. defer conn.Close()
  20. key := userLikesKey(businessID, mid, state)
  21. items, err := redis.Values(conn.Do("ZREVRANGE", key, start, end, "withscores"))
  22. if err != nil {
  23. if err == redis.ErrNil {
  24. err = nil
  25. return
  26. }
  27. err = pkgerr.Wrap(err, "get user like cache")
  28. PromError("redis:CacheUserLikeList")
  29. log.Errorv(c, log.KV("CacheUserLikeList", fmt.Sprintf("%+v", err)))
  30. return
  31. }
  32. for len(items) > 0 {
  33. var id, t int64
  34. if items, err = redis.Scan(items, &id, &t); err != nil {
  35. err = pkgerr.Wrap(err, "get user like cache")
  36. PromError("redis:CacheUserLikeList")
  37. log.Errorv(c, log.KV("CacheUserLikeList", fmt.Sprintf("%+v", err)))
  38. return
  39. }
  40. res = append(res, &model.ItemLikeRecord{MessageID: id, Time: xtime.Time(t)})
  41. }
  42. return
  43. }
  44. // ExpireUserLikesCache .
  45. func (d *Dao) ExpireUserLikesCache(c context.Context, mid, businessID int64, state int8) (ok bool, err error) {
  46. conn := d.redis.Get(c)
  47. defer conn.Close()
  48. key := userLikesKey(businessID, mid, state)
  49. if ok, err = redis.Bool(conn.Do("EXPIRE", key, d.redisUserLikesExpire)); err != nil {
  50. err = pkgerr.Wrap(err, "")
  51. PromError("redis:expire用户点赞列表")
  52. log.Errorv(c, log.KV("log", fmt.Sprintf("conn.Send(EXPIRE, %s) error(%v)", key, err)))
  53. }
  54. return
  55. }
  56. // UserLikeExists .
  57. func (d *Dao) UserLikeExists(c context.Context, mid, businessID int64, messageIDs []int64, state int8) (res map[int64]*pb.UserLikeState, err error) {
  58. conn := d.redis.Get(c)
  59. defer conn.Close()
  60. key := userLikesKey(businessID, mid, state)
  61. res = make(map[int64]*pb.UserLikeState)
  62. prom.CacheHit.Incr("userLikeList")
  63. for _, name := range messageIDs {
  64. conn.Send("ZSCORE", key, name)
  65. }
  66. if err = conn.Flush(); err != nil {
  67. err = pkgerr.Wrap(err, "")
  68. PromError("redis:UserLikeExists")
  69. log.Errorv(c, log.KV("log", fmt.Sprintf("conn.Flush() error(%v)", err)))
  70. return
  71. }
  72. for _, name := range messageIDs {
  73. var ts int64
  74. if ts, err = redis.Int64(conn.Receive()); err == nil {
  75. res[name] = &pb.UserLikeState{
  76. Mid: mid,
  77. Time: xtime.Time(ts),
  78. State: pb.State(state),
  79. }
  80. } else if err == redis.ErrNil {
  81. err = nil
  82. } else {
  83. err = pkgerr.Wrap(err, "")
  84. PromError("redis:UserLikeExists")
  85. log.Errorv(c, log.KV("log", fmt.Sprintf("UserLikeExists conn.Receive() error(%v)", err)))
  86. return
  87. }
  88. }
  89. return
  90. }
  91. // AppendCacheUserLikeList .
  92. func (d *Dao) AppendCacheUserLikeList(c context.Context, mid int64, item *model.ItemLikeRecord, businessID int64, state int8) (err error) {
  93. if item == nil {
  94. return
  95. }
  96. limit := d.BusinessIDMap[businessID].UserLikesLimit
  97. var count int
  98. conn := d.redis.Get(c)
  99. defer conn.Close()
  100. key := userLikesKey(businessID, mid, state)
  101. id := item.MessageID
  102. score := int64(item.Time)
  103. if err = conn.Send("ZADD", key, "CH", score, id); err != nil {
  104. err = pkgerr.Wrap(err, "")
  105. PromError("redis:用户点赞列表")
  106. log.Errorv(c, log.KV("log", fmt.Sprintf("conn.Send(ZADD, %s, %d, %v) error(%v)", key, score, id, err)))
  107. return
  108. }
  109. count++
  110. if err = conn.Send("ZREMRANGEBYRANK", key, 0, -(limit + 1)); err != nil {
  111. err = pkgerr.Wrap(err, "")
  112. PromError("redis:用户点赞列表rm")
  113. log.Errorv(c, log.KV("log", fmt.Sprintf("conn.Send(ZREMRANGEBYRANK, %s, 0, %d) error(%v)", key, -(limit+1), err)))
  114. return
  115. }
  116. count++
  117. if err = conn.Send("EXPIRE", key, d.redisUserLikesExpire); err != nil {
  118. err = pkgerr.Wrap(err, "")
  119. PromError("redis:用户点赞列表过期")
  120. log.Errorv(c, log.KV("log", fmt.Sprintf("conn.Send(EXPIRE, %s, %d) error(%v)", key, d.redisUserLikesExpire, err)))
  121. return
  122. }
  123. count++
  124. if err = conn.Flush(); err != nil {
  125. PromError("redis:用户点赞列表flush")
  126. log.Errorv(c, log.KV("log", fmt.Sprintf("conn.Flush error(%v)", err)))
  127. return
  128. }
  129. for i := 0; i < count; i++ {
  130. if _, err = conn.Receive(); err != nil {
  131. err = pkgerr.Wrap(err, "")
  132. PromError("redis:用户点赞列表receive")
  133. log.Errorv(c, log.KV("log", fmt.Sprintf("conn.Receive error(%v)", err)))
  134. return
  135. }
  136. }
  137. return
  138. }
  139. // DelUserLikeCache .
  140. func (d *Dao) DelUserLikeCache(c context.Context, mid, businessID int64, messageID int64, state int8) (err error) {
  141. conn := d.redis.Get(c)
  142. defer conn.Close()
  143. key := userLikesKey(businessID, mid, state)
  144. if _, err = conn.Do("ZREM", key, messageID); err != nil {
  145. err = pkgerr.Wrap(err, "")
  146. PromError("redis:zrem用户点赞列表")
  147. log.Errorv(c, log.KV("log", fmt.Sprintf("conn.Send(ZREM, %s, %v) error(%v)", key, messageID, err)))
  148. }
  149. return
  150. }
  151. // UserLikesCountCache .
  152. func (d *Dao) UserLikesCountCache(c context.Context, businessID, mid int64) (res int, err error) {
  153. conn := d.redis.Get(c)
  154. defer conn.Close()
  155. key := userLikesKey(businessID, mid, model.StateLike)
  156. res, err = redis.Int(conn.Do("ZCOUNT", key, "(0", "+inf"))
  157. if err != nil {
  158. err = pkgerr.Wrap(err, "")
  159. log.Errorv(c, log.KV("log", fmt.Sprintf("dao.UserLikesCountCache(%d, %d) err:%v", businessID, mid, err)))
  160. PromError("redis:用户点赞总数")
  161. }
  162. return
  163. }