Как ограничить повтор и спасение в этом примере Ruby?
В скромной книге Ruby приведен пример использования Rescue и 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 }
Ответы
Ответ 1
Вы можете просто написать 5.times
плюс a 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
Ответ 2
Вы можете установить переменную в 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
Ответ 3
Я использовал эту функцию для запуска и повторного запуска команды несколько раз с прерывистой задержкой. Оказывается, аргумент 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