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

Discussion in 'Ruby' started by Dan, Feb 22, 2010.

  1. Dan

    Dan Guest

    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.
    Dan, Feb 22, 2010
    #1
    1. Advertising

  2. On 22.02.2010 19:53, Dan wrote:
    > 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


    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Feb 22, 2010
    #2
    1. Advertising

  3. Dan

    Kirk Haines Guest

    On Mon, Feb 22, 2010 at 11:53 AM, Dan <> wrote:
    > 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
    Kirk Haines, Feb 22, 2010
    #3
  4. Dan

    Marcelo Guest

    On Mon, Feb 22, 2010 at 12:53, Dan <> wrote:

    > 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
    Marcelo, Feb 22, 2010
    #4
  5. On Mon, Feb 22, 2010 at 1:53 PM, Dan <> wrote:
    > 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
    Rick DeNatale, Feb 22, 2010
    #5
  6. On Feb 22, 11:53=A0am, Dan <> wrote:
    > 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
    Daniel Berger, Feb 22, 2010
    #6
  7. Dan wrote:
    > 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
    Joel VanderWerf, Feb 22, 2010
    #7
  8. Dan

    Marc Heiler Guest

    attempt() looks actually pretty cool.

    Wonder if it would support this as well :D

    attempt("twice", "10 minutes"){
    open('http://www.example.com/foo.html')
    }


    hehe :D
    --
    Posted via http://www.ruby-forum.com/.
    Marc Heiler, Feb 23, 2010
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sixteenmillion

    The giving that keeps on giving

    sixteenmillion, Nov 19, 2007, in forum: C Programming
    Replies:
    0
    Views:
    415
    sixteenmillion
    Nov 19, 2007
  2. Peña, Botp

    request for times, step, upto...

    Peña, Botp, Jan 14, 2005, in forum: Ruby
    Replies:
    4
    Views:
    104
    Kristof Bastiaensen
    Jan 14, 2005
  3. Jason Wong
    Replies:
    0
    Views:
    158
    Jason Wong
    Nov 20, 2007
  4. MRAB
    Replies:
    0
    Views:
    164
  5. andrea crotti

    Re: retry many times decorator

    andrea crotti, Jun 28, 2012, in forum: Python
    Replies:
    5
    Views:
    240
    Justin Barber
    Jun 29, 2012
Loading...

Share This Page