Мы создаем поддерживаемую AMQP систему обмена сообщениями в Ruby. Однако у нас есть проблема с обработкой ошибок.
Мы поддерживаем белый список исключений, которые являются безопасными, и сообщение в RabbitMQ может быть оставлено без подтверждения и повторно проверено другим работником. Тем не менее, при неизвестных или непредвиденных ошибках мы предполагаем, что один и тот же сбой всегда будет происходить независимо от того, сколько раз сообщение было проверено работником.
Это означает, что когда возникает неизвестная ошибка, нам нужно ее зафиксировать, зарегистрировать где-нибудь (в настоящее время MySQL), а затем отправить ACK
вызов RabbitMQ для удаления сообщения из очереди.
В настоящее время все построено с использованием гема amqp, который выравнивается с EventMachine. Это вызывает проблему, поскольку вызов метода #ack
не означает, что ACK
было отправлено в RabbitMQ благодаря асинхронному поведению самоцвета.
Ранее я обошел эту проблему, грубо поместив код повышения в EM.next_tick
. Теперь нам нужно обеспечить многопоточность каждого работника Ruby для повышения производительности, а next_tick
не работает.
Короче говоря:
Как бы вы поступили, выполняя определенный фрагмент кода синхронно сразу после асинхронного вызова ACK в геме amqp? Обратный вызов был бы хорош, но нет ни одного доступного, по крайней мере, без какого-либо серьезного злобного исправления обезьян.