You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

queue.go 2.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package mqs
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/pkg/errors"
  6. "github.com/redis/go-redis/v9"
  7. "github.com/zeromicro/go-zero/core/queue"
  8. "github.com/zeromicro/go-zero/core/service"
  9. "github.com/zeromicro/go-zero/core/threading"
  10. )
  11. type (
  12. ConsumeHandle func(v string) error
  13. ConsumeHandler interface {
  14. Consume(value string) error
  15. }
  16. redisQueues struct {
  17. queues []queue.MessageQueue
  18. group *service.ServiceGroup
  19. }
  20. redisQueue struct {
  21. topic string
  22. channel chan redis.Message
  23. client *redis.Client
  24. handler ConsumeHandler
  25. consumerRoutines *threading.RoutineGroup
  26. producerRoutines *threading.RoutineGroup
  27. }
  28. )
  29. func (r *redisQueue) Start() {
  30. r.startConsumers()
  31. r.startProducers()
  32. r.producerRoutines.Wait()
  33. close(r.channel)
  34. r.consumerRoutines.Wait()
  35. }
  36. func (r *redisQueue) Stop() {
  37. }
  38. func (r redisQueues) Start() {
  39. for _, each := range r.queues {
  40. r.group.Add(each)
  41. }
  42. r.group.Start()
  43. }
  44. func (r redisQueues) Stop() {
  45. r.group.Stop()
  46. }
  47. func (r *redisQueue) startConsumers() {
  48. r.consumerRoutines.Run(func() {
  49. for message := range r.channel {
  50. if err := r.consumeOne(message.Payload); err != nil {
  51. fmt.Errorf("consume: %s, error: %v", message.Payload, err)
  52. }
  53. }
  54. })
  55. }
  56. func (r *redisQueue) consumeOne(value string) error {
  57. err := r.handler.Consume(value)
  58. return err
  59. }
  60. func (r *redisQueue) startProducers() {
  61. r.producerRoutines.Run(func() {
  62. for {
  63. channel := r.client.Subscribe(context.Background(), r.topic).Channel()
  64. for msg := range channel {
  65. fmt.Println("生产者获取的值:", msg.Payload)
  66. r.channel <- *msg
  67. }
  68. }
  69. })
  70. }
  71. func newRedisQueue(topic string, redisClient *redis.Client, handler ConsumeHandler) queue.MessageQueue {
  72. return &redisQueue{
  73. topic: topic,
  74. client: redisClient,
  75. channel: make(chan redis.Message),
  76. producerRoutines: threading.NewRoutineGroup(),
  77. consumerRoutines: threading.NewRoutineGroup(),
  78. handler: handler}
  79. }
  80. func MustNewQueue(topic string, redisClient *redis.Client, handler ConsumeHandler) queue.MessageQueue {
  81. q, err := NewQueue(topic, redisClient, handler)
  82. if err != nil {
  83. fmt.Println("NewQueue报错")
  84. }
  85. return q
  86. }
  87. func NewQueue(topic string, redisClient *redis.Client, handler ConsumeHandler) (queue.MessageQueue, error) {
  88. if len(topic) == 0 {
  89. return nil, errors.New("topic不能为空")
  90. }
  91. r := redisQueues{
  92. group: service.NewServiceGroup(),
  93. }
  94. r.queues = append(r.queues, newRedisQueue(topic, redisClient, handler))
  95. return r, nil
  96. }

PCM is positioned as Software stack over Cloud, aiming to build the standards and ecology of heterogeneous cloud collaboration for JCC in a non intrusive and autonomous peer-to-peer manner.