Created
August 23, 2016 16:54
-
-
Save fornellas/e71b69e964056f204e09773f1b2f150c to your computer and use it in GitHub Desktop.
Retry Proxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RetryProxy < BasicObject | |
def initialize target, retries, logger=nil | |
@target = target | |
@retries = retries | |
@logger = logger | |
end | |
BasicObject.instance_methods.each do |basic_object_instance_method| | |
define_method(basic_object_instance_method) do |*args, &block| | |
@target.send(basic_object_instance_method, *args, &block) | |
end | |
end | |
def method_missing symbol, *args, &block | |
retries = @retries | |
begin | |
@target.send(symbol, *args, &block) | |
rescue | |
retries -= 1 | |
::Kernel.raise $! if retries == 0 | |
message = "While calling #{@target.to_s} (#{@target.class}) received exception, will retry: #{$!} (#{$!.class})" | |
@logger.warn(message) if @logger | |
retry | |
end | |
end | |
end | |
class FailOnce | |
def initialize | |
@fail = true | |
end | |
def fail | |
if @fail | |
@fail = false | |
raise "Fail at first!" | |
else | |
"Now it works!" | |
end | |
end | |
def == other | |
true | |
end | |
end | |
require 'logger' | |
target = FailOnce.new | |
proxy_target = RetryProxy.new(target, 3, Logger.new(STDOUT)) | |
p(proxy_target.fail) | |
# BasicObject instance methods are also delegated | |
p(proxy_target == 3) | |
# >> W, [2016-08-23T13:54:37.259614 #25557] WARN -- : While calling #<FailOnce:0x007fcfe39d5778> (FailOnce) received exception, will retry: Fail at first! (RuntimeError) | |
# >> "Now it works!" | |
# >> true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment