How to reference an active delayed_job within the actual job

I am working on a solution to display the percentage completion of a delayed job (using the delayed_job gem). I currently have a database migration that looks like this for my delayed_jobs table:

class CreateDelayedJobs < ActiveRecord::Migration
  def self.up
    create_table :delayed_jobs, :force => true do |table|
      table.integer  :priority, :default => 0      # Allows some jobs to jump to the front of the queue
      table.integer  :attempts, :default => 0      # Provides for retries, but still fail eventually.
      table.text     :handler                      # YAML-encoded string of the object that will do work
      table.text     :last_error                   # reason for last failure (See Note below)
      table.datetime :run_at                       # When to run. Could be Time.zone.now for immediately, or sometime in the future.
      table.datetime :locked_at                    # Set when a client is working on this object
      table.datetime :failed_at                    # Set when all retries have failed (actually, by default, the record is deleted instead)
      table.string   :locked_by                    # Who is working on this object (if locked)
      table.string   :queue                        # The name of the queue this job is in
      table.integer  :progress
      table.timestamps

    end

    add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
  end

  def self.down
    drop_table :delayed_jobs
  end
end

      

I am using a queue process in a controller method for a deferred job and referencing the class in lib / build_detail.rb:

Delayed::Job.enqueue(BuildDetail.new(@object, @com))

      

The lib / build_detail.rb file looks like this:

class BuildDetail < Struct.new(:object, :com)

  def perform
    total_count = object.person_ids.length
    progress_count = 0

    people = com.person object.person_ids do |abc|
      progress_count += abc.size
      Delayed::Job.current.update_attribute :progress, (progress_count/total_count)
    end
  end  

end

      

Delayed :: Job.current doesn't work. I see the Delayed :: Job.current method suggested in this post , however it looks like this method was never included in the main delayed_jobs gmailub project.

How can I access the current assignment (from within the actual assignment) to update the progress field every time my work goes through a loop?

+3


source to share


2 answers


Eventually to answer, but I ran into the same requirement, maybe it will help someone. All you have to do is do a custom job and before

-hook where you will store the link on the current job:



class MyTestJob
  def before(job)
    @job = job
  end

  def perform
    ...
    @job.update_attributes({ progress: your_progress_var }, without_protection: true)
  end
end

      

+7


source


One of the great things about delayed work is also what gets in your way here. When you queue a lot of pending jobs, you can work on them in parallel if you have multiple instances of employees working - for example. you can have 10 machines, each running an instance of your application accessing the same database, and getting 10x faster processing times. Because of this, there may be several "ongoing" jobs. Performing only one task at a time is a special case.

This shows a way to view all active jobs. If you only have one instance, it will only return one job to suit your situation:



active_jobs = Delayed::Job.where("progress > 0")
progress_of_first_job = active_jobs.first.progress if active_jobs.present?
progress_of_all_jobs = active_jobs.map{|job| job.progress}

      

progress_of_first_job is the progress of one of the tasks (use the order clause to be safe). progress_of_all_jobs - (possibly empty) array of progress values ​​for each active job.

0


source







All Articles