Aydar Omurbekov
Aydar Omurbekov

Reputation: 2127

Resque jobs, how to stop running job

My Resque worker class

class WebWorker

  @queue = :jobs_queue

  def self.perform(id)
  //bunch of code here
  end
end

I remove from the queue a certain job like this

Resque.dequeue(WebWorker,id)

But I would like to stop running job and restart, how would I do this?

Upvotes: 14

Views: 10495

Answers (2)

Aakash Gupta
Aakash Gupta

Reputation: 756

If you feel like killing/stopping an ongoing job without marking it as a failed job, you can use this hack.

class Task

    @queue = :queue_name

    def self.perform(parameters)

        pid = Process.fork do
            Task.work parameters
        end

        #puts "parent, pid #{Process.pid}, waiting on child pid #{pid}"
        Process.wait
    end

    def self.work(parameters)
        #Your perform code here
    end
end

Now, where you want your stop this code, just reach to the resque worker currently doing the job which you want to stop. and kill its child's child process. Something like killing grandchild process of Worker.

Explanation:

A worker forks a child process in which perform function run its code. If we directly kill this child process, then this job will stop but it will be marked as failed job. That's why we have forked another child process in self.perform and now killing perform's child process will stop this running job and also, it will not be marked as failed. Now we can again enqueue the job. So, the task is to how to reach to the worker doing the job that we need to stop (._.")

I have managed to do this by writing this code for a UNIX based system:

Resque.workers.each do |worker|
    #If condition : "current worker is working and is working on the job that we want to stop and is operating on the queue that we require " and please change this condition as per your requirement          
    if worker.working? and worker.queues.include?("queue_name") and worker.job["payload"]["args"].first==post_id
            victim = %x[pgrep -P #{worker.pid}] #Getting child's PID
            victim.strip!
            victim = %x[pgrep -P #{victim}] #Getting grandchild's PID of worker
            victim.strip!
            %x[kill -9 #{victim.to_i}]
    end
end

Upvotes: 1

joaofraga
joaofraga

Reputation: 643

Try the unregister_worker as follow:

Resque.workers.each(&:unregister_worker)

This command will stop the work and set it as failed.

http://www.rubydoc.info/gems/resque/Resque/Worker:unregister_worker

Upvotes: 15

Related Questions