Как вы ограничиваете повторные попытки и восстановление в этом примере Ruby? - PullRequest
14 голосов
/ 23 января 2011

В скромной книге Ruby приведен пример использования Rescue and retry для отправки HTTP-заголовков на сервер с помощью следующего кода:

def make_request
  if (@http11)
    self.send('HTTP/1.1')
  else
    self.send('HTTP/1.0')
  end
rescue ProtocolError
  @http11 = false
  retry
end

Чтобы ограничить бесконечный цикл, если он не 'Не могу решить, какой код мне нужно вставить, чтобы ограничить количество попыток, чтобы сказать 5 раз?Было бы что-то вроде:

5.times { retry }

Ответы [ 3 ]

18 голосов
/ 23 января 2011

Вы можете просто написать 5.times плюс break в случае успеха внутри цикла или абстрагировать шаблон, чтобы отделить логику от цикла.Идея:

module Kernel
  def with_rescue(exceptions, retries: 5)
    try = 0
    begin
      yield try
    rescue *exceptions => exc
      try += 1
      try <= retries ? retry : raise
    end
  end
end

with_rescue([ProtocolError], retries: 5) do |try|
  protocol = (try == 0) ? 'HTTP/1.1' : 'HTTP/1.0'
  send(protocol)
end
3 голосов
/ 23 января 2011

Вы можете установить переменную в 0 и увеличивать ее при каждой попытке, пока не будет достигнут ваш максимум, например:

def make_request
  limiter = 0
  ...
rescue ProtocolError
  @http11 = false
  if limiter < MAXIMUM
    retry
  end
end

Кроме того, вы можете попробовать это сами:

def make_request
  raise ProtocolError
rescue ProtocolError
  try_to_find_how_to_limit_it
end
2 голосов
/ 05 июня 2014

Я использовал эту функцию для запуска и повторения команды ограниченное количество раз с периодической задержкой. Оказывается, аргумент tries может быть просто расширен в теле функции и передается при вызове retry.

def run_and_retry_on_exception(cmd, tries: 0, max_tries: 3, delay: 10)
  tries += 1
  run_or_raise(cmd)
rescue SomeException => exception
  report_exception(exception, cmd: cmd)
  unless tries >= max_tries
    sleep delay
    retry
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...