Resque作业,如何停止运行作业

时间:2013-11-20 13:41:36

标签: ruby-on-rails delayed-job resque

我的Resque工人阶级

class WebWorker

  @queue = :jobs_queue

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

我从队列中删除了一个像这样的工作

Resque.dequeue(WebWorker,id)

但是我想停止运行并重新启动,我该怎么做?

2 个答案:

答案 0 :(得分:12)

尝试unregister_worker,如下所示:

Resque.workers.each(&:unregister_worker)

此命令将停止工作并将其设置为失败。

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

答案 1 :(得分:1)

如果你想杀死/停止正在进行的工作而不将其标记为失败的工作,你可以使用这个黑客。

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

现在,您希望停止此代码,只需访问当前正在执行您要停止的作业的resque工作人员。并杀死孩子的孩子过程。就像杀死工人的孙子过程一样。

<强>解释

一个worker分叉子进程,其中perform函数运行其代码。如果我们直接杀死此子进程,则此作业将停止,但它将被标记为失败的作业。这就是为什么我们在self.perform中分叉了另一个子进程,现在kill执行的子进程将停止这个正在运行的作业,并且它也不会被标记为失败。现在我们可以再次排队。所以,任务是如何联系到我们需要停止工作的工人(._。“)

我已经设法通过为基于UNIX的系统编写此代码来实现此目的:

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