Connection and channel pool/cache?

157 views
Skip to first unread message

Andrew Powell

unread,
Jun 19, 2021, 7:38:55 AM6/19/21
to rabbitmq-users
Hi All

I have a questions about connection and channel reuse/pools?


Reading the documentation in several places says that channels should be reused and they should be long lived, long lived it very fluffy term.

For example if I have a web api that needs to publish messages from, do I need to store the connection as a static one or have a collection of static ones?

If I am to reuse channels do I need a collection/pool/cache of them where I can dequeue one and check if it is good, then use it and put it back on the queue? or do I just create a new channel each time like all the examples (which the documentation says we should not do!)

There is also mention of a channel per thread, this confuses me as with a .net core web api I presume this just happens and I dont have to create my own threads/task? 

Many thanks for your help, Andrew

Brian Richardson

unread,
Jun 19, 2021, 9:55:01 AM6/19/21
to rabbitm...@googlegroups.com

Hi Andrew,

 

My approach was to decorate the .NET API to add things like channel tracking and reuse and request/response correlation. It’s not meant for production use, but I think it illustrates channel and connection management reasonably well. You can have a look at https://github.com/cubikca/RabbitWarren.git

 

I’ll try a TLDR though. I try to have 1-2 channels per queue, one for read and one for write. If I need a channel for a queue, I check to see if I already have one for that queue and create it if necessary. The channel gets added to the connection’s collection of channels, and the connection is stored as a singleton service in the web apps DI container. This results in connections having the lifetime of the application (which is generally considered to be “long-lived”) and channels having as long a life as is feasible.

 

Now, the last issue is that of multi-threading. For example, something like this:

 

var tasks = myCollection.Select(async x => await DoPublishAsync(x)); await Task.WhenAll(tasks);

 

The advice given in the documentation is that each call to DoPublishAsync() should get its own channel. I haven’t followed this advice, locking the channel object instead when publishing. I’ve yet to run into problems doing so, but I’ll advise to follow the documentation. You are correct in that you can generally assume your web application code to be a single thread unless you’ve explicitly added asynchronous code that creates new tasks.

 

If you’re going to be moving to using RabbitMQ in your production applications, I’d suggest you don’t “roll your own”. There are many good libraries out there (https://masstransit-project.com, e.g.) that will abstract away the nuts and bolts of asynchronous messaging allowing you to focus on writing the consumers and producers.

 

Regards,

Brian

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-user...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/rabbitmq-users/d70b32e7-1a52-4cae-b8ae-b2dbed6f44ban%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages