micro--go-micro
3e885308a0
Fixes #2988. Brings 'golangci-lint run ./...' to zero issues (was ~373): - errcheck: explicitly ignore fire-and-forget calls with '_ =' (and a small errcheck.exclude-functions list for response writes — json Encoder.Encode, http ResponseWriter.Write, fmt.Fprint*); genuine cases handled. - unused: remove dead code (unexported decls and dead test helpers) and the imports they orphaned. - staticcheck: ST1005 error strings, ST1016 receiver names, S1000/S1017/S1019/ S1023 simplifications, SA4004/SA4006/SA4010 dead code, SA1021 net.IP.Equal, SA6002 (store *[]byte in sync.Pool). - govet: fix a context leak (lostcancel) in internal/util/mdns and move t.Fatal/Fatalf out of goroutines (testinggoroutine) in tests. - ineffassign, unconvert: mechanical fixes. CI: the Lint workflow now runs a blocking full-tree 'golangci-lint run' on pushes and PRs (dropped only-new-issues now that the tree is clean). Verified: go build, go vet, test compilation, and unit tests for the behaviourally-touched packages all pass. Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL Co-authored-by: Claude <noreply@anthropic.com>
179 行
3.8 KiB
Go
179 行
3.8 KiB
Go
package rabbitmq
|
|
|
|
//
|
|
// All credit to Mondo
|
|
//
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
|
|
"github.com/google/uuid"
|
|
amqp "github.com/rabbitmq/amqp091-go"
|
|
)
|
|
|
|
type rabbitMQChannel struct {
|
|
uuid string
|
|
connection *amqp.Connection
|
|
channel *amqp.Channel
|
|
confirmPublish chan amqp.Confirmation
|
|
mtx sync.Mutex
|
|
}
|
|
|
|
func newRabbitChannel(conn *amqp.Connection, prefetchCount int, prefetchGlobal bool, confirmPublish bool) (*rabbitMQChannel, error) {
|
|
id, err := uuid.NewRandom()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rabbitCh := &rabbitMQChannel{
|
|
uuid: id.String(),
|
|
connection: conn,
|
|
}
|
|
if err := rabbitCh.Connect(prefetchCount, prefetchGlobal, confirmPublish); err != nil {
|
|
return nil, err
|
|
}
|
|
return rabbitCh, nil
|
|
}
|
|
|
|
func (r *rabbitMQChannel) Connect(prefetchCount int, prefetchGlobal bool, confirmPublish bool) error {
|
|
var err error
|
|
r.channel, err = r.connection.Channel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = r.channel.Qos(prefetchCount, 0, prefetchGlobal)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if confirmPublish {
|
|
r.confirmPublish = r.channel.NotifyPublish(make(chan amqp.Confirmation, 1))
|
|
|
|
err = r.channel.Confirm(false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *rabbitMQChannel) Close() error {
|
|
if r.channel == nil {
|
|
return errors.New("channel is nil")
|
|
}
|
|
return r.channel.Close()
|
|
}
|
|
|
|
func (r *rabbitMQChannel) Publish(exchange, key string, message amqp.Publishing) error {
|
|
if r.channel == nil {
|
|
return errors.New("channel is nil")
|
|
}
|
|
|
|
if r.confirmPublish != nil {
|
|
r.mtx.Lock()
|
|
defer r.mtx.Unlock()
|
|
}
|
|
|
|
err := r.channel.Publish(exchange, key, false, false, message)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if r.confirmPublish != nil {
|
|
confirmation, ok := <-r.confirmPublish
|
|
if !ok {
|
|
return errors.New("channel closed before could receive confirmation of publish")
|
|
}
|
|
|
|
if !confirmation.Ack {
|
|
return errors.New("could not publish message, received nack from broker on confirmation")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *rabbitMQChannel) DeclareExchange(ex Exchange) error {
|
|
return r.channel.ExchangeDeclare(
|
|
ex.Name, // name
|
|
string(ex.Type), // kind
|
|
ex.Durable, // durable
|
|
false, // autoDelete
|
|
false, // internal
|
|
false, // noWait
|
|
nil, // args
|
|
)
|
|
}
|
|
|
|
func (r *rabbitMQChannel) DeclareDurableExchange(ex Exchange) error {
|
|
return r.channel.ExchangeDeclare(
|
|
ex.Name, // name
|
|
string(ex.Type), // kind
|
|
true, // durable
|
|
false, // autoDelete
|
|
false, // internal
|
|
false, // noWait
|
|
nil, // args
|
|
)
|
|
}
|
|
|
|
func (r *rabbitMQChannel) DeclareQueue(queue string, args amqp.Table) error {
|
|
_, err := r.channel.QueueDeclare(
|
|
queue, // name
|
|
false, // durable
|
|
true, // autoDelete
|
|
false, // exclusive
|
|
false, // noWait
|
|
args, // args
|
|
)
|
|
return err
|
|
}
|
|
|
|
func (r *rabbitMQChannel) DeclareDurableQueue(queue string, args amqp.Table) error {
|
|
_, err := r.channel.QueueDeclare(
|
|
queue, // name
|
|
true, // durable
|
|
false, // autoDelete
|
|
false, // exclusive
|
|
false, // noWait
|
|
args, // args
|
|
)
|
|
return err
|
|
}
|
|
|
|
func (r *rabbitMQChannel) DeclareReplyQueue(queue string) error {
|
|
_, err := r.channel.QueueDeclare(
|
|
queue, // name
|
|
false, // durable
|
|
true, // autoDelete
|
|
true, // exclusive
|
|
false, // noWait
|
|
nil, // args
|
|
)
|
|
return err
|
|
}
|
|
|
|
func (r *rabbitMQChannel) ConsumeQueue(queue string, autoAck bool) (<-chan amqp.Delivery, error) {
|
|
return r.channel.Consume(
|
|
queue, // queue
|
|
r.uuid, // consumer
|
|
autoAck, // autoAck
|
|
false, // exclusive
|
|
false, // nolocal
|
|
false, // nowait
|
|
nil, // args
|
|
)
|
|
}
|
|
|
|
func (r *rabbitMQChannel) BindQueue(queue, key, exchange string, args amqp.Table) error {
|
|
return r.channel.QueueBind(
|
|
queue, // name
|
|
key, // key
|
|
exchange, // exchange
|
|
false, // noWait
|
|
args, // args
|
|
)
|
|
}
|