У меня есть вариант использования RabbitMQ и драгоценного камня Sneakers, где у меня запущено несколько рабочих процессов, отвечающих на несколько десятков очередей в моем проекте. Поэтому очень вероятно, что рабочие процессы могут одновременно обрабатывать сообщения из одной и той же очереди.
В частности, с одной очередью — назовем ее :one_at_a_time
— я хочу, чтобы только один рабочий процесс мог обрабатывать сообщение из очереди в любой момент времени.
Причина, по которой я хочу это сделать, заключается в том, что рабочий процесс предназначен для выполнения следующих действий:
- Поиск объекта AR по переданному идентификатору
- Check that an attribute - let's say :worked - is set.
- If
true
, thenack!
the message. - Если
false
, отправьте электронное письмо пользователю, а затем установите для:worked
значение true.
- If
Это разработано таким образом, чтобы я случайно не отправил пользователю электронное письмо дважды, если два сообщения создаются в быстрой последовательности с одним и тем же идентификатором объекта. И этот дизайн будет работать нормально, если только один рабочий процесс когда-либо прослушивал эту очередь в любой момент времени, потому что первый запуск будет проходить через шаги 1 -> 2 -> 2, а следующий запуск будет проходить через шаги 1 -> 2 -> 1 и не будет отправлять пользователю электронное письмо. Но при тестировании я обнаружил, что существует возможность возникновения состояния гонки, когда два работника одновременно извлекают сообщение из очереди :one_at_a_time
, проходят проверку на то, что :worked
установлен, и оба отправляют электронное письмо.
Имея все это в виду, есть ли способ ограничить количество рабочих, которые слушают очередь? Спасибо.