In our Rails app. We save a model (Video). We have a callback on that object:
after_create :send_to_background_job, :if => :persisted?
The method looks like:
def send_to_background_job
Resque.enqueue(AddVideo, self.id)
end
When the worker is called. It does the following:
class AddVideo
@queue = :high
def self.perform(video_id)
video = Video.find(video_id)
video.original_file_name
....
Resque-web reports an error:
AddVideo
Arguments
51061
Exception
NoMethodError
Error
undefined method `original_filename' for nil:NilClass
Which is a bit odd, because, if I go to Rails console to look for this video. It does exist. Furthermore, calling Resque.enqueue(AddVideo, 51061)
a SECOND time, runs without any errors.
It is as if it takes more time to save the record in the database, than it takes to create the worker/job. But even this statement doesn't add up, since the object calls the Resque job only after the object is saved. In Rails, this is done via a callback method in the model (after_create
).
Don't know if this plays a role in the issue. In an initializer file, I have:
Resque.before_fork do
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
Resque.after_fork do
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
This probably happens because the actual transaction in which the object is saved is not yet commited and the background job already started working on it.
You should switch the after_create to
after_commit :send_to_background_job, on: :create
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With