Again I read an article about background processing that generates many different jobs which all do the same: call method a on b with parameter z. At the moment we are using one GenericJob to handle all those cases.
It serializes ActiveRecord objects to a string representation, so that they do not get submittet as instance(often too large or deserialisation problems), if you do not need this feature, :send_later could be a good option for starting with generic jobs.
Usage
GenericJob.publish UserMailer, :deliver_notification,
:args=>[user, comment], :priority=>2
Install
class GenericJob < DelayedJobBase
DEFAULT_JOB_PRIORITY = 5
# GenericJob.publish( Product, :find, :args=>[:all, {:conditions=>"1 = 2"}], :priority=>3 )
def self.publish(klass, method, options={})
args = options[:args] || []
args = GenericJob.serialize_ar(args)
priority = options[:priority] || DEFAULT_JOB_PRIORITY
Delayed::Job.enqueue self.new(:class_name => klass.to_s, :method_name => method, :args => args), priority
end
def perform
klass = message[:class_name].constantize
args = GenericJob.deserialize_ar(message[:args]||[])
klass.send(message[:method_name], *args)
end
private
def self.serialize_ar(args)
args.map do |arg|
if arg.is_a?(ActiveRecord::Base)
"ActiveRecord:#{arg.class}:#{arg.id}"
else
arg
end
end
end
def self.deserialize_ar(args)
args.map do |arg|
if arg.to_s =~ /^ActiveRecord:(\w+):(\d+)$/
$1.constantize.find($2)
else
arg
end
end
end
end
Like this:
Like Loading...
Related
One thought on “Solving Background Processing with a Single, Generic Background Job”