Deliver_later

На одному проекті інтернет-магазину виникали помилка після завершення оформлення замовлення. В момент надсилання email повідомлення адміністратору магазину про нове замовлення, відбулась проблема з'єднання із SMTP-сервером, в наслідок чого користувач бачив у браузері помилку

Теоретично такого не мало б відбутися, оскільки за змовчанням у ActiveJob використовується ansync адаптер і виклик методу deliver_later мав би виконатися у фоновому режимі

Але ActiveJob виконувався синхроно, було б добре розібратися чому саме так.

Для вирішення даної проблеми, використаємо gem sidekiq який дозволяє rails породжувати нові процеси, які будуть працювати у фоновому режимі.  В основі гема задіяна модель акторів. Його інсталяція досить проста – додати гем в Gemfile:

Вказуємо сервер черги у config/application.rb:

Інсталюємо Redis сервер

Оскільки отримання email'а є важливим, задаю 100 спроб у разі невдачі

В development середовищі запускається досить просто:

Перевірка показала асинхронну роботу

Для деплоя добавляємо у Gemfile gem:

Добавляємо в Capfile

Як бачимо у нас буде інтегація з monit, який буде запускати sidekiq у разі його падіння, тому на продакшені інсталюємо його

В /etc/monit/monitrc дозволяємо http для localhost'у

Та перезапускаємо 

Action Mailer використовує чергу mailers, задаємо її для sidekiq у config/deploy.rb

Далі деплоємо проект