feed.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package dao
  2. import (
  3. "context"
  4. "fmt"
  5. "go-common/app/interface/bbq/app-bbq/model"
  6. "go-common/library/cache/redis"
  7. "go-common/library/time"
  8. "go-common/library/xstr"
  9. "strconv"
  10. "go-common/library/log"
  11. )
  12. // FetchAvailableOutboxList 根据提供的up主mids去获取比lastSvID还小的svid
  13. // @param CursorID 函数并不判断SvID正确性,由调用方保证
  14. // @param cursorNext 表明fetch的方向,同时会影响排序顺序
  15. // true: 则有如下条件sql"... and id < {{svid}} order by id desc..."
  16. // false: 则有如下条件sql"... and id > {{svid}} order by id asc..."
  17. // @return svIDs 注意:svid的返回有顺序
  18. func (d *Dao) FetchAvailableOutboxList(c context.Context, fetchStates string, mids []int64, cursorNext bool, cursorSvID int64, cursorPubtime time.Time, size int) (svIDs []int64, err error) {
  19. if len(mids) == 0 {
  20. return
  21. }
  22. compareSymbol := string(">=")
  23. orderDirection := "asc"
  24. if cursorNext {
  25. compareSymbol = "<="
  26. orderDirection = "desc"
  27. }
  28. midStr := xstr.JoinInts(mids)
  29. // 多个字段order by,每个字段都要指定desc,否则不带的字段为asc
  30. querySQL := fmt.Sprintf("select svid, pubtime from video where mid in (%s) and state in (%s) and "+
  31. "pubtime %s ? order by pubtime %s, svid %s limit %d",
  32. midStr, fetchStates, compareSymbol, orderDirection, orderDirection, size)
  33. log.V(1).Infov(c, log.KV("event", "mysql_select"), log.KV("table", "video"),
  34. log.KV("sql", querySQL))
  35. rows, err := d.db.Query(c, querySQL, cursorPubtime)
  36. if err != nil {
  37. log.Errorv(c, log.KV("event", "mysql_select"), log.KV("table", "video"),
  38. log.KV("sql", querySQL))
  39. return
  40. }
  41. defer rows.Close()
  42. var svID int64
  43. var pubTIme time.Time
  44. conflict := bool(true)
  45. for rows.Next() {
  46. if err = rows.Scan(&svID, &pubTIme); err != nil {
  47. log.Errorv(c, log.KV("event", "mysql_scan"), log.KV("table", "video"),
  48. log.KV("sql", querySQL))
  49. return
  50. }
  51. // 为了解决同一个pubtime的冲突问题
  52. if pubTIme == cursorPubtime && conflict {
  53. if svID == cursorSvID {
  54. conflict = false
  55. }
  56. continue
  57. }
  58. svIDs = append(svIDs, svID)
  59. }
  60. log.Infov(c, log.KV("event", "mysql_select"), log.KV("table", "video"),
  61. log.KV("desc", "fetch outbox"), log.KV("size", len(svIDs)))
  62. return
  63. }
  64. // SetMIDLastPubtime redis设置
  65. func (d *Dao) SetMIDLastPubtime(c context.Context, mid int64, pubtime int64) (err error) {
  66. key := fmt.Sprintf(model.CacheKeyLastPubtime, mid)
  67. conn := d.redis.Get(c)
  68. defer conn.Close()
  69. _, err = conn.Do("set", key, pubtime, "ex", model.CacheExpireLastPubtime)
  70. if err != nil {
  71. log.Errorv(c, log.KV("event", "redis_set"), log.KV("key", key), log.KV("value", pubtime))
  72. }
  73. return
  74. }
  75. // GetMIDLastPubtime 获取该用户feed中的最新浏览svid
  76. func (d *Dao) GetMIDLastPubtime(c context.Context, mid int64) (pubtime int64, err error) {
  77. pubtime = 0
  78. key := fmt.Sprintf(model.CacheKeyLastPubtime, mid)
  79. conn := d.redis.Get(c)
  80. defer conn.Close()
  81. var data []byte
  82. if data, err = redis.Bytes(conn.Do("get", key)); err != nil {
  83. if err == redis.ErrNil {
  84. err = nil
  85. log.V(1).Infov(c, log.KV("event", "redis_get"), log.KV("key", key), log.KV("result", "not_found"))
  86. } else {
  87. log.Errorv(c, log.KV("event", "redis_get"), log.KV("key", key))
  88. }
  89. return
  90. }
  91. pubtime, err = strconv.ParseInt(string(data), 10, 0)
  92. if err != nil {
  93. log.Errorv(c, log.KV("event", "redis_get"), log.KV("key", key), log.KV("value", data))
  94. }
  95. return
  96. }