如何编写Resque条件,说明“如果进程运行的时间超过n秒,则将其删除”?

时间:2011-09-21 18:54:56

标签: ruby resque god

我有一个神/ resque设置,跨越一些工作服务器。每隔一段时间,工人就会被长时间的轮询连接堵塞,并且不会正确地超时。我们已经尝试过围绕它进行编码(但不管它为什么不起作用),从线路发送的保持活动数据包不会让我们轻易地将其计时。

我希望某些工作人员(我已经在他们自己的监视区块中进行了细分)不允许运行超过一定时间。在pesudocode中,我正在寻找如下所示的监视条件(例如,如果完成任务需要超过60秒,则重新启动该工作人员):

w.transition(:up, :restart) do |on|
  on.condition(:process_timer) do {|c|  c.greater_than = 60.seconds}
end

非常感谢任何有关如何实现这一目标的想法或指示。

4 个答案:

答案 0 :(得分:1)

require 'timeout'
Timeout::timeout(60) do
  ...
end

答案 1 :(得分:1)

虽然你有一个答案我会把它放在这里,因为我已经做到了:

class TimedThread
  def initialize(limit, &block)
    @thread = Thread.new{ block.call }
    @start = Time.now
    Thread.new do
      while @thread.alive?
        if Time.now - @start > limit
          @thread.kill
          puts "Thread killed"
        end
      end
    end.join
  end
end

[1, 2, 3].each_with_index do |secs, i|
  TimedThread.new(2.5){ sleep secs ; puts "Finished with #{i+1}" }
end

答案 2 :(得分:0)

事实证明,在一些示例resque文件中有一个如何执行此操作的示例。这不是我想要的,因为它没有添加on.condition(:foo),但它是一个可行的解决方案:

# This will ride alongside god and kill any rogue stale worker
# processes. Their sacrifice is for the greater good.

WORKER_TIMEOUT = 60 * 10 # 10 minutes

Thread.new do
  loop do
    begin
      `ps -e -o pid,command | grep [r]esque`.split("\n").each do |line|
        parts   = line.split(' ')
        next if parts[-2] != "at"
        started = parts[-1].to_i
        elapsed = Time.now - Time.at(started)

        if elapsed >= WORKER_TIMEOUT
          ::Process.kill('USR1', parts[0].to_i)
        end
      end
    rescue
      # don't die because of stupid exceptions
      nil
    end

    # Sleep so we don't run too frequently
    sleep 30
  end
end

答案 3 :(得分:0)

也许看看resque-restriction?它似乎没有进行主动维护,但可能会满足您的需求。