How to DRY this up?

I have some API calls I’m making, all with the following sort of
begin-rescue-end wrapper:

(pseudo-code)

retries = 0
begin
response = SomeAPI.api_method1(:request => { ‘ThisId’ => this_id })
rescue API::Exception => e
retries.succ
sleep( retries * 5 )
retry unless retries > 2
end

where there are multiple api_methods and request forms. Seems like I
should be able to DRY this instead of doing this everywhere I have to
make this sort of API call.

On Thu, Jan 24, 2013 at 6:18 PM, tamouse mailing lists
[email protected] wrote:

sleep( retries * 5 )
retry unless retries > 2
end

where there are multiple api_methods and request forms. Seems like I
should be able to DRY this instead of doing this everywhere I have to
make this sort of API call.

You could create a method for it (untested):

def call_with_retries obj, method, *args, retries=2
begin
response = obj.send(method, *args)
rescue API::Exception => e
retries -= 1
sleep( retries * 5 )
retry unless retries < 0
end
end

and call it like

call_with_retries SomeApi, :api_method1, :request => { ‘ThisId’ =>
this_id }

You could also pass the exception to rescue, or just rescue
StandardError, and also pass the time to sleep.
Hope this gives you some ideas.

Jesus.

You can create a class that represents the api connection and use
method_missing
to collect all the API calls to one place in your code, like this:

class ApiWrapperClass
def method_missing(meth, *args)
retries = 0
begin
SomeAPI.send(meth, *args)
rescue API::Exception

end
end

x = ApiWrapperClass.new
x.api_call( … )

On Thu, Jan 24, 2013 at 6:18 PM, tamouse mailing lists <

On Thu, Jan 24, 2013 at 6:29 PM, Jess Gabriel y Galn
[email protected] wrote:

rescue API::Exception => e
retries.succ

That #succ won’t do anything because the result is not stored.

sleep( retries * 5 )
retry unless retries > 2

You are sleeping too much here because after the last attempt you are
sleeping as well. Reason is that the decision to retry is made after
sleeping. Grouping that in an if end would be better.

response = obj.send(method, *args)

You could also pass the exception to rescue, or just rescue
StandardError, and also pass the time to sleep.
Hope this gives you some ideas.

I’d rather put the code to invoke into a block because it gives much
more flexibility and separates concerns:

def retry_code(retries = 2)
count ||= 0
yield
rescue API::Exception => e
count += 1

if count <= retries
sleep count * 5
retry
end
end

response = retry_code { SomeAPI.api_method1(:request => { ‘ThisId’ =>
this_id }) }

Kind regards

robert

On Thu, Jan 24, 2013 at 3:47 PM, tamouse mailing lists
[email protected] wrote:

On Thu, Jan 24, 2013 at 11:55 AM, Robert K.

I’d rather put the code to invoke into a block because it gives much
more flexibility and separates concerns:

Thanks, robert – I very much like your version.

And that’s how I ended up writing it. The more I look at this, the
more chuffy it feels. Very awesome! Very ruby! Feels just the best of
OO and Functional rolled together.

On Thu, Jan 24, 2013 at 11:55 AM, Robert K.
[email protected] wrote:

begin
sleeping as well. Reason is that the decision to retry is made after
def call_with_retries obj, method, *args, retries=2

count ||= 0
response = retry_code { SomeAPI.api_method1(:request => { ‘ThisId’ =>
this_id }) }

Kind regards

robert


remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Thanks, robert – I very much like your version.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs