I'm using ActiveJob with delayed_job (4.0.6) in the background and I want to find a scheduled job to deleted it.
For instance, if I have
class MyClass
def my_method
perform_stuff
MyJob.set(wait: 1.month.from_now).perform_later(current_user)
end
end
Then, if I edit MyClass instance and call my_method again, I want to cancel that job and schedule a new one.
As suggested in this post http://www.sitepoint.com/delayed-jobs-best-practices, I added two columns to the Delayed Job Table:
table.integer :delayed_reference_id
table.string :delayed_reference_type
add_index :delayed_jobs, [:delayed_reference_id], :name => 'delayed_jobs_delayed_reference_id'
add_index :delayed_jobs, [:delayed_reference_type], :name => 'delayed_jobs_delayed_reference_type'
So this way I may find a delayed Job and destroy it. But I wanted to do that inside a ActiveJob class, to maintain the pattern of jobs in my project.
I wanted to do something like:
class MyJob < ActiveJob::Base
after_enqueue do |job|
user = self.arguments.first
job.delayed_reference_id = user.id,
job.delayed_reference_type = "User"
end
def perform(user)
delete_previous_job_if_exists(user_id)
end
def delete_previous_job_if_exists(user_id)
Delayed::Job.find_by(delayed_reference_id: 1, delayed_reference_type: 'User').delete
end
end
But that doesn't work.
Anyone had this kind of issue?
Two changes:
1. updated the after_enqueue callback so that you can update the
delayed_jobs table directly
2. fixed a typo where delayed_reference_id
was hard coded as 1
This should work:
class MyJob < ActiveJob::Base
after_enqueue do |job|
user = self.arguments.first
delayed_job = Delayed::Job.find(job.provider_job_id)
delayed_job.update(delayed_reference_id:user.id,delayed_reference_type:'User')
end
def perform(user)
delete_previous_job_if_exists(user.id)
end
def delete_previous_job_if_exists(user_id)
Delayed::Job.find_by(delayed_reference_id: user_id, delayed_reference_type: 'User').delete
end
end