streamx.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package redisx
  2. import (
  3. "context"
  4. "time"
  5. "github.com/redis/go-redis/v9"
  6. )
  7. // Stream(流)封装
  8. // 添加消息
  9. func XAdd(ctx context.Context, stream string, values map[string]interface{}) (string, error) {
  10. return getClient().XAdd(ctx, &redis.XAddArgs{
  11. Stream: stream,
  12. Values: values,
  13. }).Result()
  14. }
  15. // 读取消息
  16. func XRead(ctx context.Context, streams map[string]string, count int64) ([]redis.XStream, error) {
  17. args := &redis.XReadArgs{
  18. Streams: flattenStreams(streams),
  19. Count: count,
  20. Block: 0,
  21. }
  22. return getClient().XRead(ctx, args).Result()
  23. }
  24. // 创建消费者组
  25. func XGroupCreate(ctx context.Context, stream, group, start string) error {
  26. return getClient().XGroupCreateMkStream(ctx, stream, group, start).Err()
  27. }
  28. // 从消费者组读取
  29. func XReadGroup(ctx context.Context, group, consumer string, streams map[string]string, count int64) ([]redis.XStream, error) {
  30. args := &redis.XReadGroupArgs{
  31. Group: group,
  32. Consumer: consumer,
  33. Streams: flattenStreams(streams),
  34. Count: count,
  35. Block: 5 * time.Second,
  36. }
  37. return getClient().XReadGroup(ctx, args).Result()
  38. }
  39. // 从消费者组读取滞留消息
  40. func XAutoClaim(ctx context.Context, stream string, group string, consumer string, idle time.Duration, count int64) (messages []redis.XMessage, start string, err error) {
  41. args := &redis.XAutoClaimArgs{
  42. Stream: stream,
  43. Group: group,
  44. Consumer: consumer,
  45. Start: "-", // 从最小ID开始
  46. Count: count,
  47. MinIdle: idle,
  48. }
  49. return getClient().XAutoClaim(ctx, args).Result()
  50. }
  51. // 从消费者组读取指定ID的Pending状态信息
  52. func XPendingExtOne(ctx context.Context, stream string, group string, consumer string, id string) (*redis.XPendingExt, error) {
  53. args := &redis.XPendingExtArgs{
  54. Stream: stream,
  55. Group: group,
  56. Consumer: consumer,
  57. Count: 1,
  58. Idle: 0,
  59. Start: id,
  60. End: id,
  61. }
  62. res, err := getClient().XPendingExt(ctx, args).Result()
  63. if err != nil {
  64. return nil, err
  65. }
  66. if len(res) == 0 {
  67. return nil, nil
  68. }
  69. return &res[0], nil
  70. }
  71. // 确认消息
  72. func XAck(ctx context.Context, stream, group string, ids ...string) error {
  73. return getClient().XAck(ctx, stream, group, ids...).Err()
  74. }
  75. // 确认同时删除消息
  76. func XAckDel(ctx context.Context, stream, group string, ids ...string) error {
  77. // 版本不支持合并写法
  78. // return getClient().XAckDel(ctx, stream, group, "DEL", ids...).Err()
  79. err := getClient().XAck(ctx, stream, group, ids...).Err()
  80. if err != nil {
  81. return err
  82. }
  83. return getClient().XDel(ctx, stream, ids...).Err()
  84. }
  85. // 查询范围内指定的消息信息
  86. func XRangeN(ctx context.Context, stream, start, stop string, count int64) ([]redis.XMessage, error) {
  87. return getClient().XRangeN(ctx, stream, start, stop, count).Result()
  88. }
  89. // 获取完整的Stream信息
  90. func XInfoStreamFull(ctx context.Context, key string, count int) (*redis.XInfoStreamFull, error) {
  91. return getClient().XInfoStreamFull(ctx, key, count).Result()
  92. }
  93. func flattenStreams(m map[string]string) []string {
  94. arr := make([]string, 0, len(m)*2)
  95. for k, v := range m {
  96. arr = append(arr, k, v)
  97. }
  98. return arr
  99. }