Jerome
Jerome

Reputation: 6179

Moving Mailer action to Resque queue

A controller action calls TextMailer.contact(fg, mailing).deliver_now, however this needs to be moved into a background job at a determined time with resque-scheduler gem.

Thus the controller action would now invoke:

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

a new rake task is set with Resque...

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

to run a delayed_mailer job

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

There are two syntactic elements which need clarifying.

1) does the perform method need to invoke the time value (it appears counter-intuitive as calling Resque with enqueue_at explicitly gives a time key, which implicitly is not necessary to repeat) ?

2) can the ActionMailer method be invoked without futher change, as it was running before, or does the queue somehow interrupt some logic ?

Upvotes: 0

Views: 981

Answers (1)

You can configure resque to work with ActionMailer.

  1. Add gem 'resque' to your gemfile.
  2. Make change to adapter in application.rb - config.active_job.queue_adapter = :resque
  3. Use the following to generate a job - 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

In your controller, you can do

SendEmail.set(wait: 10.seconds).perform_later(@fg.id, @mailing.id)

Upvotes: 1

Related Questions