go-micro.dev/v5@v5.12.0/broker/rabbitmq/channel.go (about) 1 package rabbitmq 2 3 // 4 // All credit to Mondo 5 // 6 7 import ( 8 "errors" 9 "sync" 10 11 "github.com/google/uuid" 12 amqp "github.com/rabbitmq/amqp091-go" 13 ) 14 15 type rabbitMQChannel struct { 16 uuid string 17 connection *amqp.Connection 18 channel *amqp.Channel 19 confirmPublish chan amqp.Confirmation 20 mtx sync.Mutex 21 } 22 23 func newRabbitChannel(conn *amqp.Connection, prefetchCount int, prefetchGlobal bool, confirmPublish bool) (*rabbitMQChannel, error) { 24 id, err := uuid.NewRandom() 25 if err != nil { 26 return nil, err 27 } 28 rabbitCh := &rabbitMQChannel{ 29 uuid: id.String(), 30 connection: conn, 31 } 32 if err := rabbitCh.Connect(prefetchCount, prefetchGlobal, confirmPublish); err != nil { 33 return nil, err 34 } 35 return rabbitCh, nil 36 } 37 38 func (r *rabbitMQChannel) Connect(prefetchCount int, prefetchGlobal bool, confirmPublish bool) error { 39 var err error 40 r.channel, err = r.connection.Channel() 41 if err != nil { 42 return err 43 } 44 45 err = r.channel.Qos(prefetchCount, 0, prefetchGlobal) 46 if err != nil { 47 return err 48 } 49 50 if confirmPublish { 51 r.confirmPublish = r.channel.NotifyPublish(make(chan amqp.Confirmation, 1)) 52 53 err = r.channel.Confirm(false) 54 if err != nil { 55 return err 56 } 57 } 58 59 return nil 60 } 61 62 func (r *rabbitMQChannel) Close() error { 63 if r.channel == nil { 64 return errors.New("Channel is nil") 65 } 66 return r.channel.Close() 67 } 68 69 func (r *rabbitMQChannel) Publish(exchange, key string, message amqp.Publishing) error { 70 if r.channel == nil { 71 return errors.New("Channel is nil") 72 } 73 74 if r.confirmPublish != nil { 75 r.mtx.Lock() 76 defer r.mtx.Unlock() 77 } 78 79 err := r.channel.Publish(exchange, key, false, false, message) 80 if err != nil { 81 return err 82 } 83 84 if r.confirmPublish != nil { 85 confirmation, ok := <-r.confirmPublish 86 if !ok { 87 return errors.New("Channel closed before could receive confirmation of publish") 88 } 89 90 if !confirmation.Ack { 91 return errors.New("Could not publish message, received nack from broker on confirmation") 92 } 93 } 94 95 return nil 96 } 97 98 func (r *rabbitMQChannel) DeclareExchange(ex Exchange) error { 99 return r.channel.ExchangeDeclare( 100 ex.Name, // name 101 string(ex.Type), // kind 102 ex.Durable, // durable 103 false, // autoDelete 104 false, // internal 105 false, // noWait 106 nil, // args 107 ) 108 } 109 110 func (r *rabbitMQChannel) DeclareDurableExchange(ex Exchange) error { 111 return r.channel.ExchangeDeclare( 112 ex.Name, // name 113 string(ex.Type), // kind 114 true, // durable 115 false, // autoDelete 116 false, // internal 117 false, // noWait 118 nil, // args 119 ) 120 } 121 122 func (r *rabbitMQChannel) DeclareQueue(queue string, args amqp.Table) error { 123 _, err := r.channel.QueueDeclare( 124 queue, // name 125 false, // durable 126 true, // autoDelete 127 false, // exclusive 128 false, // noWait 129 args, // args 130 ) 131 return err 132 } 133 134 func (r *rabbitMQChannel) DeclareDurableQueue(queue string, args amqp.Table) error { 135 _, err := r.channel.QueueDeclare( 136 queue, // name 137 true, // durable 138 false, // autoDelete 139 false, // exclusive 140 false, // noWait 141 args, // args 142 ) 143 return err 144 } 145 146 func (r *rabbitMQChannel) DeclareReplyQueue(queue string) error { 147 _, err := r.channel.QueueDeclare( 148 queue, // name 149 false, // durable 150 true, // autoDelete 151 true, // exclusive 152 false, // noWait 153 nil, // args 154 ) 155 return err 156 } 157 158 func (r *rabbitMQChannel) ConsumeQueue(queue string, autoAck bool) (<-chan amqp.Delivery, error) { 159 return r.channel.Consume( 160 queue, // queue 161 r.uuid, // consumer 162 autoAck, // autoAck 163 false, // exclusive 164 false, // nolocal 165 false, // nowait 166 nil, // args 167 ) 168 } 169 170 func (r *rabbitMQChannel) BindQueue(queue, key, exchange string, args amqp.Table) error { 171 return r.channel.QueueBind( 172 queue, // name 173 key, // key 174 exchange, // exchange 175 false, // noWait 176 args, // args 177 ) 178 }