4
votes

I've been working on a project which uses rabbitmq to communicate. Recently we discovered that it would be much scalable if we used rabbit routing feature. So basically we bind the queue to several routing keys and use an exchange with type direct.

It's working like publish/subscribe. So it's possible to bind and unbind the queue to different events so consumers/subscribers only receive messages to which they're interested.

Of course, the producer/publisher now uses the binding key (event name) as routing_key to pass it to pika implementation. However, when it publishes something for a binding that doesn't exist the message is lost, i.e. when nobody bound a queue for event foo, but some publisher calls pika.basic_publish(..., routing_key='foo').

So my question is:

Is it possible to know if the message was actually published in a queue?

What I've tried:

  • Checking the return value of pika.basic_publish. It always returns None.

  • Check if there's an exception when we try to publish for a binding that doesn't exist. There is none.

  • Having an additional queue to make out of band control (since all subscribers are run by the same process). This approach doesn't feel ideal to me.

Additional info

  • Since I'm using this routing feature, the queue names are generated by rabbit. I don't have any problem if the new approach has to name the queue itself.

  • If a new approach is suggested which requires binding to exchanges instead of queues, I would like to hear them, but I would prefer to avoid them as they're not actually AMQP and are an extension implemented by rabbitmq.

  • pika version is 0.9.5

  • rabbitmq version is 2.8

Thanks a lot

2

2 Answers

8
votes

I believe the answer to your problem is the Mandatory flag in RabbitMQ:

This flag tells the server how to react if a message cannot be routed to a queue. Specifically, if mandatory is set and after running the bindings the message was placed on zero queues then the message is returned to the sender (with a basic.return). If mandatory had not been set under the same circumstances the server would silently drop the message.

This basically means, enqueue a message and if it can't be routed then return it to me. Take a look at basic_publish in the specification to turn it on.

0
votes

It may be possible to use a dead letter exchange to store messages that have not been consumed http://www.rabbitmq.com/dlx.html

I am not sure this is exactly what you are looking for but could be used for a solution.