Как мне написать условие Resque, которое говорит: «Если процесс выполняется дольше, чем n секунд, уничтожьте его»? - PullRequest
3 голосов
/ 21 сентября 2011

У меня есть настройка God / Resque, которая охватывает несколько рабочих серверов. Время от времени рабочие застревали из-за длинных подключений к опросу и не будут правильно рассчитывать время ожидания. Мы пытались его кодировать (но независимо от того, почему он не работает), пакеты поддержки активности, отправляемые по проводам, не дадут нам легко рассчитать время ожидания.

Я бы хотел, чтобы некоторым работникам (которые я уже разбил на сегменты в своих собственных блоках наблюдения) не разрешалось работать дольше определенного времени. В псевдокоде я ищу условие наблюдения, подобное следующему (то есть перезапускаем этого работника, если выполнение задачи занимает более 60 секунд):

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

Буду очень признателен за любые мысли или указания о том, как этого добиться.

Ответы [ 4 ]

1 голос
/ 27 сентября 2011

Хотя у вас есть ответ, я оставлю это здесь, так как я уже сделал это:

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
1 голос
/ 21 сентября 2011
require 'timeout'
Timeout::timeout(60) do
  ...
end
0 голосов
/ 29 января 2014

Может быть, посмотрите на ограничение-ограничение ?Кажется, он не находится в активном обслуживании, но может делать то, что вам нужно.

0 голосов
/ 27 сентября 2011

Как выясняется, есть пример того, как это сделать, в некоторых примерах файлов 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
...