Delayed::Job serializes your class, method & parameters into the handler field. We currently resort to hardcoding this serialized method into our code. This is gross.
How should we be constructing the handler so we can look up an existing queued up job?
Delayed Job, also known as DJ, makes it easy to add background tasks to your Rails applications on Heroku. You can also use Resque and many other popular background queueing libraries. Delayed Job uses your database as a queue to process background jobs.
The most simple way to check whether delayed_job is running or not, is to check at locked_by field. This field will contain the worker or process locking/processing the job. Running Delayed::Job. where('locked_by is not null') will give you some results, if there are jobs running.
This what I do:
1) Add two new columns to delayed_jobs
table
db/migrations/20110906004963_add_owner_to_delayed_jobs.rb
class AddOwnerToDelayedJobs < ActiveRecord::Migration
def self.up
add_column :delayed_jobs, :owner_type, :string
add_column :delayed_jobs, :owner_id, :integer
add_index :delayed_jobs, [:owner_type, :owner_id]
end
def self.down
remove_column :delayed_jobs, :owner_type
remove_column :delayed_jobs, :owner_id
end
end
2) Add a polymorphic association to Delayed::Job
model
config/initializers/delayed_job.rb
class Delayed::Job < ActiveRecord::Base
belongs_to :owner, :polymorphic => true
attr_accessible :owner, :owner_type, :owner_id
end
3) Monkey patch ActiveRecord::Base
to contain a jobs association
config/initializers/active_record.rb
class ActiveRecord::Base
has_many :jobs, :class_name => "Delayed::Job", :as => :owner
def send_at(time, method, *args)
Delayed::Job.transaction do
job = Delayed::Job.enqueue(Delayed::PerformableMethod.new(self,
method.to_sym, args), 10, time)
job.owner = self
job.save
end
end
def self.jobs
# to address the STI scenario we use base_class.name.
# downside: you have to write extra code to filter STI class specific instance.
Delayed::Job.find_all_by_owner_type(self.base_class.name)
end
end
4) Triggering a jobs
class Order < ActiveRecord::Base
after_create :set_reminders
def set_reminders
send_at(2.days.from_now, :send_email_reminder)
end
def send_email_reminder
end
# setting owner for handle_asynchronously notation.
def foo
end
handle_asynchronously :foo, :owner => Proc.new { |o| o }
end
5) Inspecting jobs
Order.jobs # lists all the running jobs for Order class
order1.jobs # lists all the running jobs for Order object order1
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