How do you limit retry & rescue in this Ruby example?
In the humble book of Ruby, an example of using Rescue and retry is provided of sending HTTP headers to a server using the following code:
def make_request
if (@http11)
self.send('HTTP/1.1')
else
self.send('HTTP/1.0')
end
rescue ProtocolError
@http11 = false
retry
end
To limit an infinite loop in case it doesn't resolve, what code would I have to insert to cap the retries to say 5 t开发者_如何学Goimes? Would it be something like:
5.times { retry }
You can just write a 5.times
plus a break
on success inside the loop, or abstract the pattern to keep the logic separate from the looping. An idea:
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
I used this function to run and retry a command a limited number of times with an intermittent delay. It turns out the tries
argument can simply be augmented in the function body and is passed on when retry
is called.
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
You could set a variable to 0 and increase it every time you retry, until your maximum is reached, like this:
def make_request
limiter = 0
...
rescue ProtocolError
@http11 = false
if limiter < MAXIMUM
retry
end
end
Additionally you could try it yourself with this:
def make_request
raise ProtocolError
rescue ProtocolError
try_to_find_how_to_limit_it
end
精彩评论