I have a use case with RabbitMQ and the Sneakers gem where I have multiple Workers running to respond to several dozen queues in my project. So it's very likely that workers may be processing messages from the same queue at the same time.
With one queue in particular, though - let's call it :one_at_a_time
- I only ever want one worker to be able to process a message from the queue at any given time.
The reason I want to do this is because the worker is designed to perform the following actions:
- Look up an AR object by the passed-in ID
- Check that an attribute - let's say :worked - is set.
- If
true
, thenack!
the message. - If
false
, email a user, then set:worked
to true.
- If
This is designed so that I don't accidentally email the user twice in case two messages are created in rapid succession with the same object ID. And this design would work fine if only one worker ever listened to this queue at any given time, because the first run would go through steps 1 -> 2 -> 2, then the next run would go through steps 1 -> 2 -> 1 and would not email the user. But in testing, I found that there is the potential for a race condition where two workers will pull a message off the :one_at_a_time
queue at the same time, get past the check that :worked
is set, and both send an email.
So with all this in mind, is there a way I can limit the number of workers that listen to a queue? Thank you.