amqp-rs / lapin

AMQP client library in Rust, with a clean, futures based API
MIT License
1.05k stars 92 forks source link

Basic.Consume without queue declaration #132

Closed marcelbuesing closed 6 years ago

marcelbuesing commented 6 years ago

With lapin it is currently not possible to run basic_consume without having a queue declared. In RabbitMQ sharding it states you must not declare a queue before consuming.

To consume from a sharded queue, register a consumer on the "images" pseudo-queue using the basic.consume method. RabbitMQ will attach the consumer to a shard behind the scenes. Note that consumers must not declare a queue with the same name as the sharded pseudo-queue prior to consuming. RabbitMQ-sharding

In lapin this basically results in a NotConnected. This seems to be by design because the hierarchy is currently channels->queues->consumers. I'm not sure how this is handled in other clients e.g. the Java client. But from my perspective it seems to be a better idea to structure it as channels->consumers / channels->queues. E.g. the Golang client also seems to do this. This would avoid that a queue must be declared. Looking at the AMQP reference this also seems more natural to me since the deliver does only contain the consumer tag and nothing related to the queue.

For others running into the same issue, the current workaround is to still declare the queue. Not entirely sure though if this has unintended side effects. The response of queue_declare will contain the name of the actual queue:

let queue = await!(channel.queue_declare(
    "images",
    queue_options,
    FieldTable::new(),
))?;

let consumer = await!(channel.basic_consume(
    &queue,
    &String::new(),
    BasicConsumeOptions::default(),
    FieldTable::new(),
))?;
Keruspe commented 6 years ago

Hi,

This is probably a specific behaviour of this plugin then? The internal structure channels->queues->consumers has nothing to do with the fact that you need to declare a queue first. This restriction has actually been added very recently, because people complained about consumers not working because they didn't declare the queue first and RabbitMQ doesn't support that if you don't use it with this particular plugin.

Anyway, if declaring the queue works even with that plugin, as it's idempotent, i'd say it's a good thing to do so anyway.