func Publish(messages chan *amqp.Publishing, connectionUri, exchange, routingKey string, mandatory, immediate bool, results chan *PublishResult) { var err error var conn *amqp.Connection var channel *amqp.Channel defer close(results) if conn, err = amqp.Dial(connectionUri); err != nil { results <- &PublishResult{"Failed to connect", err, true} return } defer conn.Close() if channel, err = conn.Channel(); err != nil { results <- &PublishResult{"Failed to get channel", err, true} return } pubAcks, pubNacks := channel.NotifyConfirm(make(chan uint64), make(chan uint64)) chanClose := channel.NotifyClose(make(chan *amqp.Error)) if err = channel.Confirm(false); err != nil { results <- &PublishResult{ "Failed to put channel into confirm mode", err, true, } return } for message := range messages { err = channel.Publish(exchange, routingKey, mandatory, immediate, *message) if err != nil { results <- &PublishResult{"Failed to publish message", err, false} continue } select { case err = <-chanClose: results <- &PublishResult{"Channel closed!", err, true} case <-pubAcks: results <- &PublishResult{ fmt.Sprintf("Published to exchange '%s' routing key '%v': %+v", exchange, routingKey, message), nil, false, } case <-pubNacks: results <- &PublishResult{"Received basic.nack for message", errors.New("'basic.nack'"), false} } } }