1
0
mirror of https://github.com/eventials/goevents.git synced 2025-04-26 13:48:59 +08:00

Merge pull request #46 from skrater/master

Fix producer to no block when publish fail
This commit is contained in:
Guilherme Emilio Raduenz 2019-03-15 11:35:52 -03:00 committed by GitHub
commit cb1bd81da2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -28,7 +28,6 @@ type producer struct {
conn *connection conn *connection
channel *amqplib.Channel channel *amqplib.Channel
notifyConfirm chan amqplib.Confirmation notifyConfirm chan amqplib.Confirmation
connectionClosed <-chan error
closeQueue chan bool closeQueue chan bool
config ProducerConfig config ProducerConfig
@ -55,8 +54,6 @@ func NewProducer(c messaging.Connection, exchange string) (*producer, error) {
// NewProducerConfig returns a new AMQP Producer. // NewProducerConfig returns a new AMQP Producer.
func NewProducerConfig(c messaging.Connection, exchange string, config ProducerConfig) (*producer, error) { func NewProducerConfig(c messaging.Connection, exchange string, config ProducerConfig) (*producer, error) {
conn := c.(*connection)
producer := &producer{ producer := &producer{
conn: c.(*connection), conn: c.(*connection),
config: config, config: config,
@ -64,7 +61,6 @@ func NewProducerConfig(c messaging.Connection, exchange string, config ProducerC
exchangeName: exchange, exchangeName: exchange,
notifyConfirm: make(chan amqplib.Confirmation), notifyConfirm: make(chan amqplib.Confirmation),
closeQueue: make(chan bool), closeQueue: make(chan bool),
connectionClosed: conn.NotifyConnectionClose(),
} }
err := producer.setupTopology() err := producer.setupTopology()
@ -73,6 +69,7 @@ func NewProducerConfig(c messaging.Connection, exchange string, config ProducerC
return nil, err return nil, err
} }
go producer.drainInternalQueue()
go producer.handleReestablishedConnnection() go producer.handleReestablishedConnnection()
return producer, err return producer, err
@ -134,6 +131,10 @@ func (p *producer) Close() {
close(p.closeQueue) close(p.closeQueue)
p.channel.Close() p.channel.Close()
for _, c := range p.closes {
c <- true
}
} }
// changeChannel takes a new channel to the queue, // changeChannel takes a new channel to the queue,
@ -191,9 +192,7 @@ func (p *producer) setupTopology() error {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"type": "goevents", "type": "goevents",
"sub_type": "producer", "sub_type": "producer",
}).Debug("Topology ready. Draining internal queue.") }).Debug("Topology ready.")
go p.drainInternalQueue()
return nil return nil
} }
@ -217,6 +216,11 @@ func (p *producer) handleReestablishedConnnection() {
} }
func (p *producer) publishMessage(msg amqplib.Publishing, queue string) (err error) { func (p *producer) publishMessage(msg amqplib.Publishing, queue string) (err error) {
if !p.conn.IsConnected() {
err = errors.New("connection is not open")
return
}
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"action": queue, "action": queue,
"body": msg.Body, "body": msg.Body,
@ -241,11 +245,6 @@ func (p *producer) publishMessage(msg amqplib.Publishing, queue string) (err err
} }
}() }()
if !p.conn.IsConnected() {
err = errors.New("connection is not open")
return
}
err = p.channel.Publish(p.exchangeName, queue, false, false, msg) err = p.channel.Publish(p.exchangeName, queue, false, false, msg)
if err != nil { if err != nil {
@ -257,6 +256,9 @@ func (p *producer) publishMessage(msg amqplib.Publishing, queue string) (err err
if confirm.Ack { if confirm.Ack {
return return
} }
err = ErrNotAcked
return
case <-time.After(p.config.publishInterval): case <-time.After(p.config.publishInterval):
err = ErrNotAcked err = ErrNotAcked
return return
@ -277,9 +279,10 @@ func (p *producer) drainInternalQueue() {
select { select {
case <-p.closeQueue: case <-p.closeQueue:
return return
case <-p.connectionClosed:
return
case m := <-p.internalQueue: case m := <-p.internalQueue:
retry := true
for retry {
// block until confirmation // block until confirmation
err := p.publishMessage(m.msg, m.action) err := p.publishMessage(m.msg, m.action)
@ -293,14 +296,12 @@ func (p *producer) drainInternalQueue() {
"sub_type": "producer", "sub_type": "producer",
}).Error("Error publishing message to the exchange. Retrying...") }).Error("Error publishing message to the exchange. Retrying...")
p.internalQueue <- m time.Sleep(p.config.publishInterval)
} else { } else {
p.wg.Done() p.wg.Done()
retry = false
} }
} }
} }
for _, c := range p.closes {
c <- true
} }
} }