def retryable(options = {}, &block) opts = { :tries => 1, :on => Exception }.merge(options) retry_exception, retries = opts[:on], opts[:tries] begin return yield rescue retry_exception retry if (retries -= 1) > 0 end yield end
If I modify this just a little bit, I can avoid the double yield while retrying and eventually failing. Here's the modified version:
def do_it_over_again(options = {}, &block) opts = { :tries => 1, :on => Exception }.merge(options) retry_exception, retries = opts[:on], opts[:tries] begin return yield rescue retry_exception retry if (retries -= 1) > 0 raise opts[:on] end end
Notice that I raise the exception we're trying to avoid instead of yielding one more time than we expect it to.
Now, instead of this:
jruby-1.5.1 > do_it_over_again(:tries => 5, :on => CustomExceptions::RejectedLoginException) do puts "hey" raise CustomExceptions::RejectedLoginException end hey hey hey hey hey hey CustomExceptions::RejectedLoginException: CustomExceptions::RejectedLoginException from (irb):28
I get this:
jruby-1.5.1 > do_it_over_again(:tries => 5, :on => CustomExceptions::RejectedLoginException) do puts "hey" raise CustomExceptions::RejectedLoginException end hey hey hey hey hey CustomExceptions::RejectedLoginException: CustomExceptions::RejectedLoginException from (irb):10:in `do_it_over_again' from (irb):17
Notice that it runs only five times in the modified code instead of six. It's definitely worth it to check out that post though, so go ahead..
No comments:
Post a Comment