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?
Resque is our Redis-backed library for creating background jobs, placing those jobs on multiple queues, and processing them later. Background jobs can be any Ruby class or module that responds… those jobs on multiple queues, and processing them later. can do both.
If you are using Resque-scheduler then it will add more options for you in the resque-web UI. Those options allows you to view queues and manually start queuing. Other option is for viewing pending jobs in the delayed queues. Again, restart server, and refresh the browser page.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With