如何编写一个 Resque 条件来表示“如果进程运行时间超过 n 秒,则终止它”?

发布于 2024-12-05 23:18:42 字数 398 浏览 1 评论 0原文

我有一个跨越几个工作服务器的 god/resque 设置。有时,工作人员会因长轮询连接而陷入困境,并且无法正确超时。我们已经尝试围绕它进行编码(但无论为什么它不起作用),通过线路发送的保持活动数据包不会让我们轻易超时。

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

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

对于如何完成此任务的任何想法或指示,我们将不胜感激。

I have a god/resque setup that spans a few worker servers. Every so often, the workers get jammed up by long polling connections and won't time out correctly. We have tried coding around it (but regardless of why it doesn't work), the keep-alive packets being sent down the wire won't let us time it out easily.

I would like certain workers (which I already have segmented out in their own watch blocks) to not be allowed to run for longer than a certain amount of time. In pesudocode, I am looking for a watch condition like the following (i.e. restart that worker if it takes longer than 60 sec to complete the task):

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

Any thoughts or pointers on how to accomplish this would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

維他命╮ 2024-12-12 23:18:42
require 'timeout'
Timeout::timeout(60) do
  ...
end
require 'timeout'
Timeout::timeout(60) do
  ...
end
梦里泪两行 2024-12-12 23:18:42

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

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

Although you have an answer I'll drop this here since I already made it:

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
时间你老了 2024-12-12 23:18:42

事实证明,在一些示例 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

As it turns out, there is an example of how to do this in some sample resque files. It's not exactly what I was looking for since it doesn't add an on.condition(:foo), but it is a viable solution:

# 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
世界等同你 2024-12-12 23:18:42

也许看看resque-restriction?它似乎没有得到积极维护,但可能会满足您的需要。

Maybe take a look at resque-restriction? It doesn't appear to be under active maintenance but might do what you need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文