Most reliable pattern for blocking RabbitMQ subscribe in Ruby, with robust reconnect, logging, and error handling? #675
Replies: 3 comments 1 reply
-
An example of a kind of error which is not successfully handled by this pattern:
So, a major weakness in my pattern is that it isn't able to re-open a closed channel. |
Beta Was this translation helpful? Give feedback.
-
Moving the part that opens a channel into the loop would do (with an obvious risk of an infinite loop that leaks channels). Detecting a server-initiated channel close in a consumer is difficult in general but if you are willing to use a loop like that, you can check the channel right before you add a consumer (subscribe). Not really related to the conversation but this is a good example of how Erlang and Elixir make certain types of (concurrent) failure handling trivial. You wouldn't really think twice about how to achieve this in Elixir. But your version is reasonably close to somewhat similar in Ruby. |
Beta Was this translation helpful? Give feedback.
-
Thanks for your reply. You wrote: "Moving the part that opens a channel into the loop would do (with an obvious risk of an infinite loop that leaks channels)." My code sample has two loops, and exterior loop and an interior loop... which loop do you suggest I move the channel opening into? My guess is that you are saying to move the channel opening to the top of the first loop... then my code would look like this?
thanks |
Beta Was this translation helpful? Give feedback.
-
I've been using RabbitMQ with the great "bunny" gem for a few years, and it has generally worked well, but I still have not found the 100% stable pattern for a blocking subscribe, which can do all of these things:
After literally years of trying different patterns, and scouring the internet for a pattern which would achieve all of these things... below is my state-of-the-art pattern which I am currently using in production...
First -- you will notice am trying to do error handling in two different places... the final
rescue => e
statement is supposed to re-instantiate the connection and channel when either of those stop working... so far I think this sometimes works, and sometimes doesn't... after years of trying I still have not found a way to reliably recover from and re-instantiate these connections....HERE IS THE BEST PATTERN I HAVE FOUND SO FAR:
Beta Was this translation helpful? Give feedback.
All reactions