Тайм-аут Heroku при отправке писем
Я нахожусь на Heroku с пользовательским доменом, и у меня есть дополнение Redis. Мне нужна помощь, чтобы понять, как создать фоновый рабочий для уведомлений по электронной почте. Пользователи могут отправлять сообщения "Входящие" друг другу, и я хотел бы отправить уведомление по электронной почте пользователю для каждого полученного нового сообщения. У меня есть уведомления, работающие в разработке, но мне нехорошо создавать фоновые задания, которые требуются для Heroku, иначе сервер будет тайм-аут.
Контроллер сообщений:
def create
@recipient = User.find(params[:user])
current_user.send_message(@recipient, params[:body], params[:subject])
flash[:notice] = "Message has been sent!"
if request.xhr?
render :json => {:notice => flash[:notice]}
else
redirect_to :conversations
end
end
Модель пользователя:
def mailboxer_email(object)
if self.no_email
email
else
nil
end
end
Mailboxer.rb:
Mailboxer.setup do |config|
#Configures if you applications uses or no the email sending for Notifications and Messages
config.uses_emails = false
#Configures the default from for the email sent for Messages and Notifications of Mailboxer
config.default_from = "[email protected]"
#Configures the methods needed by mailboxer
config.email_method = :mailboxer_email
config.name_method = :name
#Configures if you use or not a search engine and wich one are you using
#Supported enignes: [:solr,:sphinx]
config.search_enabled = false
config.search_engine = :sphinx
end
Ответы
Ответ 1
Sidekiq - это определенно способ пойти с Heroku. Я не думаю, что почтовый ящик поддерживает конфигурацию фона из коробки. К счастью, это все еще очень легко с процессом очереди sidekiq.
- Добавьте
gem 'sidekiq'
в свой gemfile и запустите bundle
.
- Создайте рабочий файл
app/workers/message_worker.rb
.
class MessageWorker
include Sidekiq::Worker
def perform(sender_id, recipient_id, body, subject)
sender = User.find(sender_id)
recipient = User.find(recipient_id)
sender.send_message(recipient, body, subject)
end
end
- Обновите свой контроллер до очереди до рабочего.
Удалить: current_user.send_message(@recipient, params[:body], params[:subject])
Добавить: MessageWorker.perform_async(current_user.id, @recipient.id, params[:body], params[:subject])
Примечание. Вы не должны пропускать рабочие объекты ActiveRecord. Поэтому я устанавливаю этот метод для передачи идентификаторов пользователей и просматриваю их в рабочем perform
методе, а не всего объекта.
-
Наконец, перезагрузите сервер и запустите bundle exec sidekiq
. Теперь ваше приложение должно отправлять фон электронной почты.
-
При развертывании вам понадобится отдельный динамик для рабочего, который должен выглядеть следующим образом: worker: bundle exec sidekiq
. Вам также понадобится дополнение Heroku redis.
Ответ 2
Звучит как время ожидания запроса H21:
HTTP-запрос занял более 30 секунд.
Чтобы создать фоновый рабочий для этого в RoR, вы должны захватить Resque, библиотеку очередного фона для резервного копирования для RoR. Вот демонстрация. Еще одна демонстрация. И еще одно демо.
Чтобы узнать больше об использовании Resque в Heroku, вы также можете прочитать статью о героике здесь. Или этот урок (он старый, хотя). Еще один отличный учебник.
Существует также драгоценный камень resque_mailer, который ускорит процесс для вас.
gem install resque_mailer #or add it to your Gemfile & use bundler
Это довольно просто. Вот фрагмент из рабочей демонстрации автора:
class Notifier < ActionMailer::Base
include Resque::Mailer
default :from => "[email protected]"
def test(data={})
data.symbolize_keys!
Rails.logger.info "sending test mail"
Rails.logger.info "params: #{data.keys.join(',')}"
Rails.logger.info ""
@subject = data[:subject] || "Testing mail"
mail(:to => "[email protected]",
:subject => @subject)
end
end
Выполнение Notifier.test.deliver
будет доставлять почту.
Вы также можете использовать службы доставки почты, такие как SES.
Ответ 3
Sidekiq - это вариант, который вы могли бы рассмотреть. Чтобы заставить его работать, вы можете добавить что-то вроде RedisToGo, а затем настроить инициализатор для Redis. Затем на Heroku вы можете добавить что-то вроде worker: bundle exec sidekiq ...
в свой файл Procfile.
https://github.com/mperham/sidekiq/wiki/Getting-Started
Он также имеет панель мониторинга для мониторинга.
https://github.com/mperham/sidekiq/wiki/Monitoring