The first question I have is a design question really. This is my first time writing a service that uses a Queue and I am also new to Go. I am trying to determine whether I should write my worker in such a way that it simply pops one message off the queue, processes it, and the dies off. With things like Kubernetes this seems fairly trivial.
Or should I have a long-lived worker constantly waiting for new messages but that is relaunched if it dies (by a bug or accident)?
The reason I ask this question is that in order to implement the former it feels a little more "hacked up" because I have to write the following using the common go AMQP library from streadway/amqp
(read the comments):
// Pop will extract a message from the AMQP queue
func (v *Queue) Pop() (data []byte, err error) {
msgs, err := v.Channel.Consume(
v.QueueName, // queue
v.ConsmerID, // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
if err != nil {
return nil, err
}
// We have to use for .. range because Consume returns
// "<-chan Delivery" but if we only want ONE message popped off
// we return on the first one
for data := range msgs {
return data.Body, nil
}
// We should never get this far...
return nil, errors.New("Something went wrong")
}
Furthermore what is <-chan Delivery
in this case? It seems like some sort of "stream" or object that you can plug into. Is there a way to not have to write a for-loop for these data types?
EDIT: I have also discovered that it appears that this code will dequeue the ENTIRE queue even though it only does a for-loop iteration once (as show in the code above). I am not sure why this happens either?
Relevant links to code: