Перемещение действия Mailer в очередь Resque

Действие контроллера вызывает TextMailer.contact(fg, mailing).deliver_now, однако его необходимо перевести в фоновое задание в определенное время с помощью гем resque-scheduler.

Таким образом, действие контроллера теперь будет вызывать:

 Resque.enqueue_at(@time, DelayedMailer, @fg.id, @mailing.id)

с Resque поставлена ​​новая задача rake...

task "resque:setup" => :environment do
  Resque.schedule = YAML.load_file("#{Rails.root}/config/resque_schedule.yml")
  ENV['QUEUES'] = *
end

запустить задание delayed_mailer

class DelayedMailer
  @queue = :mail
    def self.perform(time, fg_id, mailing_id)
    fg = Fg.where('id = ?', fg_id).first
    mailing = Mailing.where('id = ?', mailing_id).first
    TextMailer.contact(fg, mailing).deliver_now
 end

Есть два синтаксических элемента, которые нуждаются в уточнении.

1) должен ли метод выполнения вызывать значение времени (это кажется нелогичным, поскольку вызов Resque с enqueue_at явно дает ключ времени, который неявно не нужно повторять)?

2) можно ли вызвать метод ActionMailer без дальнейших изменений, как он работал раньше, или очередь каким-то образом прерывает какую-то логику?


person Jerome    schedule 05.09.2018    source источник
comment
Я бы порекомендовал вам прочитать об ActiveJob, вы можете настроить Resque в качестве серверной части, а ActionMailer будет поддерживать методы асинхронной доставки, которые автоматически используют Resque.   -  person arieljuod    schedule 06.09.2018
comment
ну да, у меня есть. в руководстве по рельсам говорится: «вы можете определить выполнение с любым количеством аргументов»… и хотя страница resque-scheduler github определяет enqueue_at, она не указывает, нужно ли вызывать исходный вызов во время в perform (я предполагаю, что нет потому что задание уже сохранено в этот момент, очередь с задержкой сохраняется в Redis и сохраняется).   -  person Jerome    schedule 06.09.2018


Ответы (1)


Вы можете настроить resque для работы с ActionMailer.

  1. Добавьте gem 'resque' в свой gemfile.
  2. Внесите изменения в адаптер в application.rb - config.active_job.queue_adapter = :resque
  3. Используйте следующее для создания задания - rails g job SendEmail

class SendEmail< ActiveJob::Base
  queue_as :default

  def perform(fg_id, mailing_id)
    fg = Fg.where('id = ?', fg_id).first
    mailing = Mailing.where('id = ?', mailing_id).first
    TextMailer.contact(fg, mailing).deliver_now
  end
end

В вашем контроллере вы можете сделать

SendEmail.set(wait: 10.seconds).perform_later(@fg.id, @mailing.id)
person Kedarnag Mukanahallipatna    schedule 06.09.2018
comment
Это немного не соответствует действительности. Как указано в вопросах, каждое письмо помечается в определенное время переменной экземпляра @time. вот почему enqueue_at вызывается в соответствии с драгоценным камнем resque-scheduler. Отсюда два вопроса. Так как первый раз вижу ссылку на config.active_job.queue_adapter, прошу обоснуйте. Сейчас мои очереди генерируются без такого добавления. - person Jerome; 06.09.2018
comment
config.active_job.queue_adapter предназначен для настройки queueing бэкенда. - person Kedarnag Mukanahallipatna; 06.09.2018
comment
Почему вы устанавливаете @time, когда задание выполняется enqueued? - person Kedarnag Mukanahallipatna; 06.09.2018
comment
enqueue_at. это запланировано на заранее определенное время, как позволяет гем resque-scheduler. - person Jerome; 06.09.2018
comment
Что касается вашего вопроса № 2, вам не нужно вносить никаких изменений в логику метода ActionMailer. Он будет продолжать вести себя так же, изменится только вызов. - person Kedarnag Mukanahallipatna; 06.09.2018