1

我正在使用Resque处理 Rails 应用程序上的一些后台作业。

问题是客户可以取消这个工作,所以:

  • 如果作业仍在队列中:将其出列

    Resque.dequeue(GitHub::Jobs::UpdateNetworkGraph, 'repo:135325')
    
  • 如果工作已经完成:什么都不做

  • 如果作业正在运行:???

有没有办法以编程方式找到工作并在它正在运行时告诉它立即停止?我主要关心的是确保我杀死所需的工作,而不是当前正在处理的工作,因为当我询问它是否正在运行时,它可能是另一种形式,直到我杀死它。

4

2 回答 2

2

我不认为 resque 存储了process idfork 进程的,它 log虽然做到了,但我不存储进程 idchild process forked

你可以在第 139 行看到这里

关于您如何提取正在运行的 resque 作业的进程 ID 的问题,我认为使用 redis 数据结构在您的作业本身内部执行此操作的方法

running_process所以考虑下面的代码是你使用 redis hash( )创建作业的执行操作,并process_id在其中添加当前时间戳

class MyJob
 @queue = :myjob

 def self.perform
   field = Time.now.to_i
   redis.hsetnx "running_process",field,Process.pid 
   ### Rest of the code



   #### when the code is about to finish 
   ##remove the finish process from the 
   redis.hdel "running_process",field
  end

现在您可以通过简单地查询 redis "running_process" 哈希来获取所有正在运行的进程的列表,如下所示

redis.hgetall "running_process"

此处的注意事项如果resque作业失败,那么进程 ID 将永远不会被清除

哈希你所做的只是确保你交叉检查process id你收集的

从redis哈希实际上是一个running resque job

希望这有帮助

于 2012-10-29T14:54:15.790 回答
0

如果您想杀死/停止正在进行的工作而不将其标记为失败的工作,则可以使用此 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

现在,您希望在哪里停止此代码,只需联系当前正在执行您要停止的工作的 resque 工作人员。并杀死其孩子的子进程。比如杀死Worker的孙子进程。

解释:

工作人员派生一个子进程,其中执行功能运行其代码。如果我们直接杀死这个子进程,那么这个作业将停止,但它会被标记为失败的作业。这就是为什么我们在 self.perform 中派生了另一个子进程,现在杀死 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
于 2017-01-28T06:51:40.050 回答