Last active
October 15, 2016 19:03
-
-
Save eihli/5228d6b17fe3d00e3b764bd4b205a9c3 to your computer and use it in GitHub Desktop.
Composable Retriable in Ruby
This file contains hidden or 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
def attempt_to_deliver | |
rand(10) > 8 | |
end | |
class Deliverable | |
def deliver | |
if attempt_to_deliver | |
puts "Delivered" | |
true | |
else | |
false | |
end | |
end | |
def detour | |
puts "Could not deliver. Taking a detour." | |
end | |
end | |
class Retriable | |
def initialize(retriable, attempt_method, failure_method, conditions) | |
self.class.class_eval do | |
define_method(attempt_method) { | |
puts "Trying to perform #{attempt_method} on #{retriable}" | |
puts "Checking exit conditions." | |
if check(conditions).any? { |condition| condition } | |
puts "Some exit condition was true. Calling some failure callback." | |
retriable.send(failure_method) | |
else | |
puts "No exit conditions evaluated to true." | |
puts "Trying to do something that might fail." | |
if retriable.send(attempt_method) | |
puts "It worked. We can stop trying." | |
else | |
puts "It didn't work. We're trying again." | |
send(attempt_method) | |
end | |
end | |
} | |
end | |
end | |
def check(conditions) | |
conditions.map do |condition| | |
result = condition[:predicate].call(*condition[:args]) | |
condition[:after].call(condition) | |
result | |
end | |
end | |
end | |
conditions = [ | |
{ | |
args: [0, 5], | |
predicate: -> (attempt, max_attempts) { attempt > max_attempts }, | |
after: -> (condition) { condition[:args][0] += 1 } | |
} | |
] | |
deliverable = Deliverable.new | |
retriable_delivery = Retriable.new(deliverable, :deliver, :detour, conditions) | |
puts retriable_delivery.deliver | |
``` | |
~$ ruby scratch.rb | |
Trying to perform deliver on #<Deliverable:0x007f91ea184128> | |
Checking exit conditions. | |
No exit conditions evaluated to true. | |
Trying to do something that might fail. | |
It didn't work. We're trying again. | |
Trying to perform deliver on #<Deliverable:0x007f91ea184128> | |
Checking exit conditions. | |
No exit conditions evaluated to true. | |
Trying to do something that might fail. | |
It didn't work. We're trying again. | |
Trying to perform deliver on #<Deliverable:0x007f91ea184128> | |
Checking exit conditions. | |
No exit conditions evaluated to true. | |
Trying to do something that might fail. | |
Delivered | |
It worked. We can stop trying. | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment