Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I find a specific delayed job (not by id)?

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?

like image 674
chrishomer Avatar asked Sep 06 '11 21:09

chrishomer


People also ask

What are delayed jobs?

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.

How do I check if my job is delayed?

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.


1 Answers

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 
like image 56
Harish Shetty Avatar answered Sep 22 '22 06:09

Harish Shetty