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?
source to share
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
source to share
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.
source to share