Rails, callbacks, workers, and the race you never expected to lose
August 21, 2012 § 38 Comments
Consider a fairly normal pattern in a user model in Rails, sending a welcome email when a user signs up. If you’re interested in keeping your controller actions quick whilst you do this, you would probably queue the email to be sent later, like this:
class User < ActiveRecord::Base
after_save :queue_welcome_email, :on => :create
private
def queue_welcome_email
Resque.enqueue(WelcomeEmailJob, self.id)
end
end
class WelcomeEmailJob
@queue = :normal
def self.perform(user_id)
user = User.find(user_id)
UserMailer.welcome_email(user).deliver
end
end
Straightforward, right? You’d think so, but if you implemented this and ran it in a live system, you would find a small number of ActiveRecord::RecordNotFound
errors cropping up in Resque.