redis.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package upper
  2. import (
  3. "context"
  4. "strconv"
  5. "go-common/app/service/main/archive/api"
  6. feed "go-common/app/service/main/feed/model"
  7. "go-common/library/log"
  8. "go-common/library/xstr"
  9. "go-common/library/cache/redis"
  10. "github.com/pkg/errors"
  11. )
  12. const (
  13. // up items
  14. _prefixUpItems = "u3_"
  15. // unread count
  16. _prefixUnreadCount = "uc2_"
  17. )
  18. func keyUpItem(mid int64) string {
  19. return _prefixUpItems + strconv.FormatInt(mid, 10)
  20. }
  21. func keyUnreadCount(mid int64) string {
  22. return _prefixUnreadCount + strconv.FormatInt(mid%100000, 10)
  23. }
  24. func (d *Dao) UpItemCaches(c context.Context, mid int64, start, end int) (uis []*feed.Feed, aids []int64, seasonIDs []int64, err error) {
  25. var vs []interface{}
  26. conn := d.redis.Get(c)
  27. key := keyUpItem(mid)
  28. defer conn.Close()
  29. if vs, err = redis.Values(conn.Do("ZREVRANGE", key, start, end, "WITHSCORES")); err != nil {
  30. err = errors.Wrapf(err, "conn.Do(ZREVRANGE,%s,%d,%d)", key, start, end)
  31. return
  32. }
  33. uis = make([]*feed.Feed, 0, len(vs))
  34. aids = make([]int64, 0, len(vs))
  35. seasonIDs = make([]int64, 0, len(vs))
  36. Loop:
  37. for len(vs) > 0 {
  38. var (
  39. i int64
  40. value string
  41. values []int64
  42. )
  43. if vs, err = redis.Scan(vs, &value, &i); err != nil {
  44. err = errors.Wrapf(err, "%v", vs)
  45. return
  46. }
  47. if values, err = xstr.SplitInts(value); err != nil {
  48. log.Error("xstr.SplitInts(%v) error(%v)", value, err)
  49. continue Loop
  50. }
  51. if len(values) >= 2 {
  52. ua := &feed.Feed{}
  53. urs := make([]*api.Arc, 0, len(values)-2)
  54. for k, v := range values {
  55. if k == 0 {
  56. ua.Type = v
  57. } else if k == 1 {
  58. ua.ID = v
  59. switch ua.Type {
  60. case feed.ArchiveType:
  61. aids = append(aids, v)
  62. case feed.BangumiType:
  63. seasonIDs = append(seasonIDs, v)
  64. }
  65. } else if k >= 2 {
  66. switch ua.Type {
  67. case feed.ArchiveType:
  68. aids = append(aids, v)
  69. urs = append(urs, &api.Arc{Aid: v})
  70. }
  71. }
  72. }
  73. ua.Fold = urs
  74. uis = append(uis, ua)
  75. }
  76. }
  77. return
  78. }
  79. func (d *Dao) AddUpItemCaches(c context.Context, mid int64, uis ...*feed.Feed) (err error) {
  80. var (
  81. ucKey = keyUnreadCount(mid)
  82. upKey = keyUpItem(mid)
  83. conn = d.redis.Get(c)
  84. )
  85. defer conn.Close()
  86. if err = conn.Send("HSET", ucKey, mid, 0); err != nil {
  87. err = errors.Wrapf(err, "conn.Send(HSET,%s,%d,%d) error(%v)", ucKey, mid, 0)
  88. return
  89. }
  90. if err = conn.Send("ZREMRANGEBYRANK", upKey, 0, -1); err != nil {
  91. err = errors.Wrapf(err, "conn.Send(ZREMRANGEBYRANK,%s,%d,%d)", upKey, 0, -1)
  92. return
  93. }
  94. for _, ui := range uis {
  95. if ui.ID != 0 && (ui.Type == feed.ArchiveType || ui.Type == feed.BangumiType) {
  96. var vs = []int64{ui.Type, ui.ID}
  97. for _, r := range ui.Fold {
  98. if r.Aid != 0 {
  99. vs = append(vs, r.Aid)
  100. }
  101. }
  102. var (
  103. score = ui.PubDate.Time().Unix()
  104. value = xstr.JoinInts(vs)
  105. )
  106. if err = conn.Send("ZADD", upKey, score, value); err != nil {
  107. err = errors.Wrapf(err, "conn.Send(ZADD,%s,%d,%d)", upKey, score, value)
  108. return
  109. }
  110. }
  111. }
  112. if err = conn.Send("EXPIRE", upKey, d.expireRds); err != nil {
  113. err = errors.Wrapf(err, "conn.Send(EXPIRE,%s,%d)", upKey, d.expireRds)
  114. return
  115. }
  116. if err = conn.Flush(); err != nil {
  117. return
  118. }
  119. for i := 0; i < len(uis)+3; i++ {
  120. if _, err = conn.Receive(); err != nil {
  121. return
  122. }
  123. }
  124. return
  125. }
  126. func (d *Dao) ExpireUpItem(c context.Context, mid int64) (ok bool, err error) {
  127. var (
  128. key = keyUpItem(mid)
  129. conn = d.redis.Get(c)
  130. )
  131. defer conn.Close()
  132. if ok, err = redis.Bool(conn.Do("EXPIRE", key, d.expireRds)); err != nil {
  133. err = errors.Wrapf(err, "conn.Do(EXPIRE,%s,%d)", key, d.expireRds)
  134. }
  135. return
  136. }
  137. func (d *Dao) UnreadCountCache(c context.Context, mid int64) (unread int, err error) {
  138. var (
  139. key = keyUnreadCount(mid)
  140. conn = d.redis.Get(c)
  141. )
  142. defer conn.Close()
  143. if unread, err = redis.Int(conn.Do("HGET", key, mid)); err != nil {
  144. if err == redis.ErrNil {
  145. err = nil
  146. return
  147. }
  148. err = errors.Wrapf(err, "conn.Do(HGET,%s,%d)", key, mid)
  149. }
  150. return
  151. }
  152. func (d *Dao) AddUnreadCountCache(c context.Context, mid int64, unread int) (err error) {
  153. var (
  154. key = keyUnreadCount(mid)
  155. conn = d.redis.Get(c)
  156. )
  157. defer conn.Close()
  158. if _, err = conn.Do("HSET", key, mid, unread); err != nil {
  159. err = errors.Wrapf(err, "conn.DO(HSET,%s,%d,%d)", key, mid, unread)
  160. }
  161. return
  162. }