Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Re-connect Strategy using Ruby Net

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

like image 925
Matt Avatar asked Jul 29 '09 16:07

Matt


2 Answers

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
like image 174
Avdi Avatar answered Oct 07 '22 05:10

Avdi


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
like image 24
Alexander Vagin Avatar answered Oct 07 '22 06:10

Alexander Vagin