У меня есть этот проект, который по-прежнему использует задержанную работу как очередь обработки. Недавно я нашел краевой случай, который заставляет меня задавать несколько вопросов: у меня есть объект AR (я использую MySQL, между прочим), который при обновлении отправляет сообщение всем элементам ассоциации has_many. Для этого мне нужно создать все элементы этой ассоциации, чтобы вызвать на них сообщение. Это казалось достаточно справедливым, чтобы отложить вызов этого сообщения для каждого из них.Работа с задержкой обработки в Ruby: сколько не блокирует мой путь
Теперь ассоциация выросла совсем немного, где в краевом случае у меня 40000 объектов, принадлежащих к этой ассоциации. Теперь отправка сообщения включает в себя (синхронное) создание 40000 заданий с задержкой. Поскольку они происходят внутри обратного вызова после обновления, а не после фиксации, они тем самым (ab) используют одно и то же соединение, не используя никакой контекстной коммутации. Короткий вариант, у меня есть трубка из 1 оператора обновления и 40000 вложений в том же соединении. По этой причине это обновление хватит на несколько минут.
Теперь есть много способов обойти это: изменить обратный вызов после фиксации, создав одно (синхронное) задание с задержкой, которое создаст 40000 заданий (я не хочу обрабатывать объекты 40000 (AR) в одна работа, 40000 сейчас будет 120000 завтра, и это память-армагеддон) и т. д. и т. д. ...
Но я действительно рассматриваю, что переключает свою задержанную очередь обработки на resque или sidekiq. Они используют redis, поэтому производительность записи намного лучше. Они используют что-то, а не MySQL, а это значит, что соединения не будут блокировать друг друга. Моя единственная проблема: сколько 40000 пишет сразу, чтобы redis стоил мне? И: любой из этих параметров сначала сохраняет задания в памяти, а не блокирует ответ клиенту и запоздало сохраняет их в redis? Итак, мой реальный вопрос: насколько это задерживает меня в таком случае?