Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you limit retry & rescue in this Ruby example?

Tags:

ruby

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 times? Would it be something like:

5.times { retry }
like image 321
Simpleton Avatar asked Jan 23 '11 14:01

Simpleton


3 Answers

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
like image 159
tokland Avatar answered Nov 16 '22 15:11

tokland


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
like image 45
Samuel Avatar answered Nov 16 '22 16:11

Samuel


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
like image 3
linopolus Avatar answered Nov 16 '22 15:11

linopolus