Как сохранить объект только после успешного завершения delayed_job? - PullRequest
1 голос
/ 17 сентября 2010

У меня есть delayed_job, предназначенный для отправки электронной почты с использованием почтовой программы.

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

Прямо сейчас новые записи ContactEmail сохраняются даже в случае сбоя delayed_job.

Как мне исправить это так, чтобы новая ContactEmail сохранялась только после успешной отправки почтовой программы?

Вот фрагмент из задачи cron, который вызывает delayed_job:

    puts contact_email.subject

    contact_email.date_sent = Date.today
    contact_email.date_created = Date.today

    contact_email.body = email.substituted_message(contact, contact.colleagues)

    contact_email.status = "sent" 

    #Delayed::Job.enqueue OutboundMailer.deliver_campaign_email(contact,contact_email)
    Delayed::Job.enqueue SomeMailJob.new(contact,contact_email)

    contact_email.save #now save the record

Вот some_mail_job.rb

class SomeMailJob < Struct.new(:contact, :contact_email) 
   def perform
     OutboundMailer.deliver_campaign_email(contact,contact_email)
   end
 end

А вот исходящий_малер:

class OutboundMailer < Postage::Mailer 

  def campaign_email(contact,email)
    subject    email.subject
    recipients contact.email
    from       '<me@me.com>'
    sent_on    Date.today

    body       :email => email
  end

Ответы [ 2 ]

0 голосов
/ 18 сентября 2010

Вы можете обновить статус при выполнении самого задания.

Например, что-то вроде:

contact_email.status = 'queued'
contact_email.save
contact_email.delay.deliver_campaign_email

А потом в вашем ContactEmail классе что-то с эффектом

def deliver_campaign_email
  OutboundMailer.deliver_campaign_email(self.contact, self)
  self.status = 'sent'    # or handle failure and set it appropriately
  self.save
end

delayed_job содержит некоторые магические биты, которые он добавляет к вашим моделям, которые будут иметь дело с постоянством.

Для того, чтобы ваш OutboundMailer выдал исключение, вы можете сделать что-то вроде этого:

def deliver_campaign_email
  begin
    OutboundMailer.deliver_campaign_email(self.contact, self)
    self.status = 'sent'
  rescue
    self.status = 'failed' # or better yet grab the the message from the exception
  end
  self.save
end
0 голосов
/ 17 сентября 2010
  1. Вам нужна синхронная доставка, поэтому в этом случае прекратите использовать отложенную работу и выполните стандартную доставку по почте.
  2. или добавьте success столбец к вам ContactEmail - сначала сохраните его с помощью false, затем обновите работу до true
...