How do I save an object only after a delayed_job is successfully completed?
I have a delayed_job designed to send an email using a mailer.
Upon completion, I need to record that the email was sent -- I do this by saving the newly created ContactEmail.
Right now, the new ContactEmail records gets saved even if the delayed_job fails.
How do I correct that so that the new ContactEmail is only saved when the mailer is successfully sent?
Here is the snippet from the cron task which calls the 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
Here is the some_mail_job.rb
class 开发者_开发问答SomeMailJob < Struct.new(:contact, :contact_email)
def perform
OutboundMailer.deliver_campaign_email(contact,contact_email)
end
end
And here is the outbound_mailer:
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
You could update the status in the perform of the job itself.
For example, something like:
contact_email.status = 'queued'
contact_email.save
contact_email.delay.deliver_campaign_email
And then in your ContactEmail
class, something to the effect of
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 has some magic bits that it adds to your models that will deal with the persistence.
In order to deal with your OutboundMailer throwing an exception, you can do something like so:
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
- You need synchronic delivery so stop using delayed job in this case and do standard mailer delivery.
- or add
success
column to you ContactEmail - initialy save it withfalse
then update in job totrue
精彩评论