Тайм-аут выполнения ActionMailer - PullRequest
4 голосов
/ 10 июня 2010

При попытке отправить электронное письмо пользователю для сброса пароля, я получаю сообщение об ошибке тайм-аута выполнения. Другие почтовые функции работают, поэтому я знаю, что настройки конфига верны. Заголовок гласит: «Время ожидания :: Ошибка в пароле resetsController # create»

Вот пароль_ресеты_контроллера:

def create  
 @user = User.find_by_email(params[:email])  
 if @user  
  User.deliver_password_reset_instructions(@user.id)
  flash[:notice] = "Instructions to reset your password have been emailed to you. " +  
  "Please check your email."  
  redirect_to '/'  
 else  
  flash[:notice] = "No user was found with that email address"  
  render :action => :new
 end  
end

Вот метод внутри User.rb

def self.deliver_password_reset_instructions(user_id)
 user = User.find(user_id)
 user.reset_perishable_token!  
 Emailer.deliver_password_reset_instructions(user)
end

Наконец, вот фактический метод внутри emailer.rb:

default_url_options[:host] = "http://0.0.0.0:3000"  #development
 def password_reset_instructions(user)  
    @subject                            = "Application Password Reset"  
    @from                               = 'Notice@myApp.com' 
    @recipients                         = user.email  
    @sent_on                            = Time.now  
    @body["edit_password_reset_url"]    =  edit_password_reset_url(user.perishable_token)  
    @headers["X-SMTPAPI"] = "{\"category\" : \"Password Recovery\"}"#send grid category header
  end

Почему в сообщении об ошибке указано «Пароль», указывающее на тайм-аут :: ошибка

1 Ответ

1 голос
/ 05 октября 2013

Отправка электронной почты (или других длительных процессов) из потока запросов основного контроллера не является хорошей идеей. Время отправки электронной почты может истечь по ряду причин, которые не находятся под вашим контролем (например, не работает сервер исходящей электронной почты), и вы не хотите, чтобы ваш сервер приложений и пользователи пострадали из-за этого.

Лучшим подходом является использование механизма очередей, такого как отложенное задание (DJ), для постановки этих задач в электронную почту и их обработки вне потоков вашего контроллера.

См. https://github.com/collectiveidea/delayed_job

Интеграция этого (или другой системы очередей) в ваше приложение rails довольно проста. И рельсы 4, как говорят, имеют встроенные службы очередей (которые мне еще предстоит использовать) http://blog.remarkablelabs.com/2012/12/asynchronous-action-mailer-rails-4-countdown-to-2013.

Например, если вы используете DJ в своем приложении, новый код будет выглядеть ниже

def self.deliver_password_reset_instructions(user_id)
 user = User.find(user_id)
 user.reset_perishable_token!  
 # this is the only line that changes
 Emailer.delay.deliver_password_reset_instructions(user)
end

Задания сохраняются в базе данных и повторяются при возникновении ошибок, таких как тайм-ауты.

Вы можете узнать больше о DJ на странице GitHub.

...