Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cancel scheduled job with delayed_job in Rails?

I am scheduling a job to run in say, 10 minutes. How to properly cancel this particular job without using any kind of dirty extra fields in model and so on. Is there any call to remove particular job, or jobs related to specific model, instance, etc?

like image 261
mdrozdziel Avatar asked Sep 03 '10 17:09

mdrozdziel


2 Answers

disclaimer: I am not an expert user of delayed_job...

"Is there any call to remove particular job, or jobs related to specific model, instance, etc?"

Delayed::Job is just an ActiveRecord object so you can find and destroy any of those records. Depending on your use case this could be handled different ways. If someone is going to manually destroy them this could be handled through an admin interface in your web app.

# list all jobs Delayed::Job.all # find a job by id job = Delayed::Job.find(params[:id]) # delete it job.delete 

if you need some out of process task deleting jobs by 'job type' you could loop through each one and delete it if it matches your job; try this in script/console

class MyJob < Struct.new(:some_value);     def perform         # ...     end end  my_job = MyJob.new('xyz') job = Delayed::Job.enqueue(my_job, 0, 1.hour.from_now) job.name # => "MyJob" job.handler # => "--- !ruby/struct:MyJob \nsome_value: xyz\n" 

so given the above if you wanted to delete all jobs of type MyJob

Delayed::Job.all.each do |job|     if job.name == "MyJob" then         job.delete     end end 

this may or may not help for your situation? in many cases you might want to delete a MyJob but only where the :some_value attribute was 'abc' and not 'xyz'. In this case you might need to implement a 'display_name' on your MyJob object. job.name will use this if it exists

class MyJob < Struct.new(:user_id);     def perform         # ...     end      def display_name         return "MyJob-User-#{user_id}"     end  end  # store reference to a User my_job = MyJob.new(User.first.id) # users.id is 1 job = Delayed::Job.enqueue(my_job, 0, 1.hour.from_now) job.name # => "MyJob-User-1" job.handler # => "--- !ruby/struct:MyJob \nuser_id: 1\n" 

this way you could be more selective about which records to delete?

hopefully this gives you enough information on possible ways to handle it?

like image 90
house9 Avatar answered Sep 20 '22 07:09

house9


delayed_job 3 introduced a queue attribute. This can be hijacked to schedule a cancelable job.

class MyJob < Struct.new(:user_id)   def self.queue_name     "something-unique"   end    def perform     # ...   end end  #scheduler my_job = MyJob.new(User.first.id) #'cancel' pending jobs first Delayed::Job.where(queue: my_job.class.queue_name).destroy_all #queue it up Delayed::Job.enqueue(my_job,   queue: my_job.class.queue_name,   run_at: 1.hour.from_now ) 
like image 24
firien Avatar answered Sep 19 '22 07:09

firien