Ruby EventMachine + AMQP: Ensuring specific async calls happen before raising exceptions
We're building an AMQP-backed messaging system in Ruby. We have a problem with error handling however.
We maintain a whitelist of exceptions, which are safe, and the message in RabbitMQ 开发者_StackOverflowcan be left unacknowledged and retried by another worker. However, on unknown or unforeseen errors we assume the same failure will always happen no matter how many times the message is tried by a worker.
That means, when an unknown error is raised, we need to capture it, log it somewhere (MySQL currently), and then send an ACK
call to RabbitMQ to remove the message from the queue.
Everything is currently built using the amqp gem, which is evented with EventMachine. This causes a problem, cause calling the #ack
method, doesn't mean ACK
has been sent to RabbitMQ thanks to the gem's asynchronous behavior.
Previous I got around this issue via crudely putting the raise code within EM.next_tick
. Now we need to multi-thread each Ruby worker for performance, and next_tick
doesn't work.
In short:
How would you go about running a specific piece of code in a synchronous manner right after the asynchronous ACK call within the amqp gem? A callback would be nice, but there are none available, at least not without some seriously evil monkey-patching.
I'll be happy to fix it for you https://github.com/ruby-amqp/amqp/issues/issue/9 At the moment the gem doesn't behave as a well-behaved async library and there are callbacks missing on a lot of places. I'm working on fixing this issue. I'll try to fix it till the 0.7 which I'm about to release today, I hope.
精彩评论