Resque工作,如何停止正在运行的工作

14

我的Resque工作器类

class WebWorker

  @queue = :jobs_queue

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

我这样从队列中移除一个特定的任务

Resque.dequeue(WebWorker,id)

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


1
https://dev59.com/iWs05IYBdhLWcg3wJurp - snowangel
2个回答

15

8
这不仅会停止正在运行的任务,还会永久地停止整个工作进程,并且没有很好的方法可以恢复它(只有重新启动resque服务器才能恢复)。 - Ben Lee
正如@BenLee所指出的那样,在不知道它会做什么的情况下运行此命令可能会在生产环境中造成严重后果,请注意。 - Nico Brenner

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

现在,如果你想停止这段代码的运行,只需找到当前正在执行你想要停止的作业的救援工作者,并杀死它的子级进程。就像杀死Worker的孙子进程一样。 说明: Worker在其中fork了一个子进程,在该子进程中执行run函数的代码。如果我们直接杀死此子进程,则该作业将停止,但它将被标记为失败的作业。这就是为什么我们在self.perform中fork了另一个子进程,现在杀死perform的子进程将停止此运行作业,并且不会被标记为失败。现在我们可以再次将作业加入队列。因此,任务是如何到达执行我们需要停止的作业的工作者(._.")
我已经编写了以下代码来管理基于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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接