delayed_job не отправляет электронные письма, но обрабатывает задание

Я использую пример кода из delayed_job для отправки информационного бюллетеня:

class NewsletterJob < Struct.new(:subscribers)
  def perform
    subscribers.each { |subscriber| NewsletterMailer.newsletter(subscriber.id) }
  end
end

Затем я устанавливаю задание здесь:

Delayed::Job.enqueue NewsletterJob.new(Subscriber.find(:all))

Если я не использую отложенную работу, почта отправляется, поэтому она работает. Если я использую отложенную работу напрямую, почта отправляется следующим образом:

NewsletterMailer.delay.newsletter(subscriber)

В таблице вакансий в базе данных есть следующий yaml:

--- !ruby/struct:NewsletterJob
subscribers:
- !ruby/ActiveRecord:Subscriber
  attributes:
    id: '54'
    email: [email protected]
    created_at: '2013-08-09 04:44:51.113258'
    updated_at: '2013-08-09 08:26:05.934564'
    token: quVI0dhxyyentB7TJ1IO6w
- !ruby/ActiveRecord:Subscriber
  attributes:
    id: '56'
    email: [email protected]
    created_at: '2013-08-11 09:29:22.000829'
    updated_at: '2013-08-11 09:29:22.000829'
    token: a-n-yijwi38_HvGFSmetmA

Я использую MockSMTP для получения электронной почты на моем локальном компьютере.

По какой-то причине, даже если кажется, что работы обрабатывают задание, электронные письма не отправляются.

Что-то не так с ямлом?

Любая помощь приветствуется, я нуб


person chell    schedule 11.08.2013    source источник
comment
Какая у вас локальная настройка почты?   -  person Matthias    schedule 12.08.2013


Ответы (2)


Когда вы связываете delayed перед методом почтовой программы, вам не нужно вызывать deliver для него. Delayed::Job позаботится об этом за вас.

NewsletterMailer.delay.newsletter(subscriber) # No need to call `deliver` here

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

subscribers.each do |subscriber|
  NewsletterMailer.newsletter(subscriber.id).deliver # You need `deliver` here
end
person Chris Peters    schedule 11.08.2013
comment
Я изменил код, чтобы сделать так, как вы посоветовали, но он все еще не отправляет электронное письмо. Кажется, что задание обработано, так как через несколько секунд оно удаляется из таблицы заданий. Однако письмо не отправляется - person chell; 12.08.2013
comment
Вы перезапустили свой сервер/фоновый процесс Rails перед повторной попыткой? Delayed::Job будет кэшировать ваш код до перезапуска. - person Chris Peters; 12.08.2013

В конце концов оказалось, что мне нужно было назвать класс работы, используя верблюжий регистр, и поместить его в каталог lib.

#lib
NewsletterJob.rb

Затем в #application.rb мне пришлось отключить автоматическое удаление неудачных заданий, чтобы увидеть, что происходит, а также предварительно загрузить файл из библиотеки.

Delayed::Worker.destroy_failed_jobs = false
require "#{Rails.root.to_s}/lib/NewsletterJob.rb"

Все основано на ответе здесь Delayed_job не выполняет метод execute, но очищает очередь заданий

person chell    schedule 12.08.2013
comment
Я храню свои задания в lib/jobs и помещаю эту строку в config/initializers/delayed_job.rb, чтобы требовать все файлы из этого каталога: Dir[Rails.root.join("lib/jobs/**/*.rb")].each { |f| require f }. Просто предложение! - person Chris Peters; 16.08.2013