我有一个神/ resque设置,跨越一些工作服务器。每隔一段时间,工人就会被长时间的轮询连接堵塞,并且不会正确地超时。我们已经尝试过围绕它进行编码(但不管它为什么不起作用),从线路发送的保持活动数据包不会让我们轻易地将其计时。
我希望某些工作人员(我已经在他们自己的监视区块中进行了细分)不允许运行超过一定时间。在pesudocode中,我正在寻找如下所示的监视条件(例如,如果完成任务需要超过60秒,则重新启动该工作人员):
w.transition(:up, :restart) do |on|
on.condition(:process_timer) do {|c| c.greater_than = 60.seconds}
end
非常感谢任何有关如何实现这一目标的想法或指示。
答案 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?它似乎没有进行主动维护,但可能会满足您的需求。