vertx-rabbitmq-client icon indicating copy to clipboard operation
vertx-rabbitmq-client copied to clipboard

Only one channel per connection

Open amorozow42 opened this issue 6 years ago • 8 comments

As I can see from source code RabbitMQ client creates one channel on connection. While common scenario is to create one channel for consumer. Here is quote from RabbitMQ docs:

Each Channel has its own dispatch thread. For the most common use case of one Consumer per Channel, this means Consumers do not hold up other Consumers. If you have multiple Consumers per Channel be aware that a long-running Consumer may hold up dispatch of callbacks to other Consumers on that Channel.

amorozow42 avatar Dec 03 '18 10:12 amorozow42

In my synchronous rabbit library I create a map of names to channels for a single connection. Translating that to the vertx library wouldn't be a vast amount of work, but would require overloads of a lot of methods to allow the desired channel name to be passed in. The alternative would be to separate out the channel as a distinct concept, but that's a lot more work and would definitely break the existing API completely.

Yaytay avatar Nov 29 '19 07:11 Yaytay

We need channel pool object.

amorozow42 avatar Nov 29 '19 09:11 amorozow42

The problem with having a simple pool of channels is that tags are scoped to the channel, so you need to know the channel when acknowledging or confirming. That's why the Rabbit docs recommend making the channels per thread, but that's not really an option in vertx (or anything thread pool based). I found named channels the simpler than tracking the channels from a pool.

Yaytay avatar Nov 29 '19 12:11 Yaytay

Can you provide code sample which demonstrate a usage of named channels?

amorozow42 avatar Nov 29 '19 12:11 amorozow42

Only for a synchronous client library that is completely different from the vertx lib - that lib has its own Channel class and Connection::getChannel(String name) returns an open channel. To do it for the vertx client without introducing a Channel class would need something like: {code:java} void basicConsumer(String channel, String queue, QueueOptions options, Handler<AsyncResult<RabbitMQConsumer>> resultHandler); {code} With a similar name inserted for all the operations that should be for a channel. Then we'd have to modify the internal call to forChannel to work with the map of channels.

Yaytay avatar Nov 29 '19 13:11 Yaytay

Hello from 2021 :)

amorozow42 avatar Mar 12 '21 19:03 amorozow42

Hello. In order to approach this we need to come up with a design that works. A simple channel pool is not viable because notifications relate to channels (it wouldn't be possible to track IDs). So we need to know at the time of sending which channel to use. I see two basic ways this could be done, both of which completely break the existing API:

  1. Split the channel out in the API, so the client can explicitly create a channel and then interacts with that channel instead of with the client.
  2. Have named channels.

In my usage I haven't had enough channels to justify the upheaval. How many channels per process are you trying to use?

Yaytay avatar Mar 13 '21 06:03 Yaytay

I want to use separate channel for each consumer. Also there must be separate channel/channels for publishing. Ideally the client should not know anything about this details. When we create new consumer we create new channel underneath.

amorozow42 avatar Mar 16 '21 17:03 amorozow42