On Thu, Jan 24, 2013 at 6:29 PM, Jesús Gabriel y Galán
<[email protected]> wrote:
> On Thu, Jan 24, 2013 at 6:18 PM, tamouse mailing lists
> <[email protected]> wrote:
>> 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

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.

>> 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.

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

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

-- 
[email protected] | 
https://groups.google.com/d/forum/ruby-talk-google?hl=en


Reply via email to