Ruby Idiom To Retry open() Upto N Times Before Giving Up

D

Dan

I write a lot of scripts that I run once or infrequently that uses open-rui=
Occasionally I run into a web site that times out or is unavailable for a=
period of time. My normal solution is to just rerun the script manually at=
a later time and the problem goes away. What I would like to start doing i=
s rescuing the open() and retrying the open() after a delay. What would be =
the most idiomatic way to try opening a url say n times before giving up? H=
ere is my crude code for trying twice:

begin=A0=20
=A0=A0 open("http://www.example.com/foo.html")
=A0rescue=A0=20
=A0=A0 begin=A0=20
=A0=A0=A0=A0=A0 open("http://www.example.com/foo.html")
=A0=A0=A0 rescue=A0=20
=A0=A0=A0=A0=A0 #tried twice - giving up=A0=20
=A0=A0 end=A0=20
end=A0=20

I would like a more general approach using ruby idioms where I could specif=
y the maximum number of attempts and delay before giving up. Thanks for you=
r help.
 
R

Robert Klemme

I write a lot of scripts that I run once or infrequently that uses open-rui Occasionally I run into a web site that times out or is unavailable for a period of time. My normal solution is to just rerun the script manually at a later time and the problem goes away. What I would like to start doing is rescuing the open() and retrying the open() after a delay. What would be the most idiomatic way to try opening a url say n times before giving up? Here is my crude code for trying twice:

begin
open("http://www.example.com/foo.html")
rescue
begin
open("http://www.example.com/foo.html")
rescue
#tried twice - giving up
end
end

I would like a more general approach using ruby idioms where I could specify the maximum number of attempts and delay before giving up. Thanks for your help.

You can use "retry":

irb(main):017:0> attempts = 3
=> 3
irb(main):018:0> begin
irb(main):019:1* raise "Error, attempt = #{attempts}"
irb(main):020:1> rescue => e
irb(main):021:1> puts e
irb(main):022:1> attempts -= 1
irb(main):023:1> retry if attempts > 0
irb(main):024:1> puts "giving up"
irb(main):025:1> end
Error, attempt = 3
Error, attempt = 2
Error, attempt = 1
giving up
=> nil
irb(main):026:0>

Kind regards

robert
 
K

Kirk Haines

I write a lot of scripts that I run once or infrequently that uses open-r=
ui. Occasionally I run into a web site that times out or is unavailable for=
a period of time. My normal solution is to just rerun the script manually =
at a later time and the problem goes away. What I would like to start doing=
is rescuing the open() and retrying the open() after a delay. What would b=
e the most idiomatic way to try opening a url say n times before giving up?=
Here is my crude code for trying twice:
begin
=A0=A0 open("http://www.example.com/foo.html")
=A0rescue
=A0=A0 begin
=A0=A0=A0=A0=A0 open("http://www.example.com/foo.html")
=A0=A0=A0 rescue
=A0=A0=A0=A0=A0 #tried twice - giving up
=A0=A0 end
end

Use 'retry'.

This is a simple sketch of the concept:

irb(main):001:0> n =3D 0
=3D> 0
irb(main):002:0> begin
irb(main):003:1* raise "#{n} tries"
irb(main):004:1> rescue
irb(main):005:1> n +=3D 1
irb(main):006:1> retry unless n =3D=3D 3
irb(main):007:1> raise
irb(main):008:1> end
RuntimeError: 2 tries
from (irb):3
from :0


Kirk Haines
 
M

Marcelo

I would like a more general approach using ruby idioms where I could specify the maximum number of attempts and delay before giving up. Thanks for your help.

Something along the lines of:

def open_with_retry(url, n=10, delay=1)
1.upto(n) do
begin
open(url) do |handle|
yield handle
end
break
rescue
puts "Sleeping ..."
sleep delay
end
end
end

open_with_retry('http://does.not.resolve.tld/', 5, 2) do |h|
puts "Doing something with #{h.inspect}"
end

Note that this sleeps even if the last attempt failed.

Marcelo
 
R

Rick DeNatale

I write a lot of scripts that I run once or infrequently that uses open-r=
ui. Occasionally I run into a web site that times out or is unavailable for=
a period of time. My normal solution is to just rerun the script manually =
at a later time and the problem goes away. What I would like to start doing=
is rescuing the open() and retrying the open() after a delay. What would b=
e the most idiomatic way to try opening a url say n times before giving up?=
Here is my crude code for trying twice:
begin
=A0=A0 open("http://www.example.com/foo.html")
=A0rescue
=A0=A0 begin
=A0=A0=A0=A0=A0 open("http://www.example.com/foo.html")
=A0=A0=A0 rescue
=A0=A0=A0=A0=A0 #tried twice - giving up
=A0=A0 end
end

I would like a more general approach using ruby idioms where I could spec=
ify the maximum number of attempts and delay before giving up. Thanks for y=
our help.
begin
raise "oops"
rescue
retry_count =3D (retry_count || 0) + 1
puts "retry #{retry_count}"
retry unless retry_count >=3D 5
end


--=20
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
 
D

Daniel Berger

I write a lot of scripts that I run once or infrequently that uses open-r=
ui. Occasionally I run into a web site that times out or is unavailable for=
a period of time. My normal solution is to just rerun the script manually =
at a later time and the problem goes away. What I would like to start doing=
is rescuing the open() and retrying the open() after a delay. What would b=
e the most idiomatic way to try opening a url say n times before giving up?=
Here is my crude code for trying twice:
begin=A0
=A0=A0 open("http://www.example.com/foo.html")
=A0rescue=A0
=A0=A0 begin=A0
=A0=A0=A0=A0=A0 open("http://www.example.com/foo.html")
=A0=A0=A0 rescue=A0
=A0=A0=A0=A0=A0 #tried twice - giving up=A0
=A0=A0 end=A0
end=A0

I would like a more general approach using ruby idioms where I could spec=
ify the maximum number of attempts and delay before giving up. Thanks for y=
our help.

gem install attempt

# Try twice, 10 seconds apart
attempt(2, 10){
open('http://www.example.com/foo.html')
}

Regards,

Dan
 
J

Joel VanderWerf

Dan said:
I write a lot of scripts that I run once or infrequently that uses open-rui. Occasionally I run into a web site that times out or is unavailable for a period of time. My normal solution is to just rerun the script manually at a later time and the problem goes away. What I would like to start doing is rescuing the open() and retrying the open() after a delay. What would be the most idiomatic way to try opening a url say n times before giving up? Here is my crude code for trying twice:

begin
open("http://www.example.com/foo.html")
rescue
begin
open("http://www.example.com/foo.html")
rescue
#tried twice - giving up
end
end

I would like a more general approach using ruby idioms where I could specify the maximum number of attempts and delay before giving up. Thanks for your help.

Another approach (minus the delay part):

$ cat open-with-retry.rb
def open_with_retry uri, tries=3
catch :success do
tries.times do |i|
begin
throw :success, open(uri)
rescue => e
puts "try ##{i}: #{e}"
end
end
raise "Giving up"
end
end

f = open_with_retry(ARGV[0])
puts f.read

$ ruby open-with-retry.rb readme.txt
this is a file

$ ruby open-with-retry.rb noexist
try #0: No such file or directory - noexist
try #1: No such file or directory - noexist
try #2: No such file or directory - noexist
open-with-retry.rb:10:in `open_with_retry': Giving up (RuntimeError)
from open-with-retry.rb:2:in `catch'
from open-with-retry.rb:2:in `open_with_retry'
from open-with-retry.rb:14
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top