package mq import ( "context" "errors" "github.com/loveuer/esgo2dump/log" amqp "github.com/rabbitmq/amqp091-go" "time" "ultone/internal/tool" ) // PublishOpt // - MaxReconnect: publish msg auto retry with reconnect, should not be big, case memory leak type PublishOpt struct { Exchange string Mandatory bool Immediate bool MaxReconnect uint8 // publish msg auto retry with reconnect, should not be big(default 1), case memory leak } func Publish(ctx context.Context, queue string, msg amqp.Publishing, opts ...*PublishOpt) error { var ( err error opt = &PublishOpt{ Exchange: amqp.DefaultExchange, Mandatory: false, Immediate: false, MaxReconnect: 1, } retry = 0 ) if len(opts) > 0 && opts[0] != nil { opt = opts[0] } for ; retry <= int(opt.MaxReconnect); retry++ { if err = client.ch.PublishWithContext(ctx, opt.Exchange, queue, opt.Mandatory, opt.Immediate, msg); err == nil { return nil } if errors.Is(err, amqp.ErrClosed) { sleep := tool.Min(120, (retry+1)*30) log.Warn("[mq] connection closed, reconnect[%d/%d] after %d seconds", retry+1, opt.MaxReconnect, sleep) time.Sleep(time.Duration(sleep) * time.Second) if oerr := client.open(); oerr != nil { log.Error("[mq] reconnect[%d/%d] mq err: %v", oerr, retry+1, opt.MaxReconnect) } else { log.Info("[mq] reconnect mq success!!!") } continue } return err } return err }