Implementing Re-connect Strategy using Ruby Net
Asked Answered
M

2

6

I'm developing a small application which posts XML to some webservice. This is done using Net::HTTP::Post::Post. However, the service provider recommends using a re-connect.

Something like: 1st request fails -> try again after 2 seconds 2nd request fails -> try again after 5 seconds 3rd request fails -> try again after 10 seconds ...

What would be a good approach to do that? Simply running the following piece of code in a loop, catching the exception and run it again after an amount of time? Or is there any other clever way to do that? Maybe the Net package even has some built in functionality that I'm not aware of?

url = URI.parse("http://some.host")

request = Net::HTTP::Post.new(url.path)

request.body = xml

request.content_type = "text/xml"


#run this line in a loop??
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}

Thanks very much, always appreciate your support.

Matt

Mcneese answered 29/7, 2009 at 16:30 Comment(0)
M
15

This is one of the rare occasions when Ruby's retry comes in handy. Something along these lines:

retries = [3, 5, 10]
begin 
  response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
rescue SomeException # I'm too lazy to look it up
  if delay = retries.shift # will be nil if the list is empty
    sleep delay
    retry # backs up to just after the "begin"
  else
    raise # with no args re-raises original error
  end
end
Macronucleus answered 29/7, 2009 at 18:45 Comment(1)
Thanks. Btw it seems SomeException must, unfortunately be StandardError, cf: #5371197 . Not great, but at least it is scoped to a line, and not swallowed if it is a non-transient, actual error.Delaney
V
2

I use gem retryable for retry. With it code transformed from:

retries = [3, 5, 10]
begin 
  response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
rescue SomeException # I'm too lazy to look it up
  if delay = retries.shift # will be nil if the list is empty
    sleep delay
    retry # backs up to just after the "begin"
  else
    raise # with no args re-raises original error
  end
end

To:

retryable( :tries => 10, :on => [SomeException] ) do
  response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
end
Verism answered 21/5, 2013 at 6:2 Comment(1)
they are not equal: first is doing 4 ties with delays 0,3,5,10; second is doing 10 tries with 1 second delay.Dentifrice

© 2022 - 2024 — McMap. All rights reserved.