class CircuitBreaker::Redis
Attributes
(look to {CircuitBreaker::Memory#circuit})
An instance of an redis client. This library does not have a hard dependency on a particular redis client but for testing I’ve used [redis-rb](github.com/redis/redis-rb). Whatever you pass in here simply has to implement a few redis commands such as ‘sadd`, `del`, `smembers`, `get` and `set`. The client will ensure these exist before the breaker can be instantiated. @return [Object] - redis client given
(look to {CircuitBreaker::Memory#failure_limit})
(look to {CircuitBreaker::Memory#failures})
(look to {CircuitBreaker::Memory#logger})
A unique name that will be used across servers to sync state and failures. I’d recommend ‘your_class.name:your_method_name` or whatever is special about what’s being invoked in the ‘circuit`. See examples/example_redis.rb @return [String] - namespace given
(look to {CircuitBreaker::Memory#reset_timeout})
(look to {CircuitBreaker::Memory#state})
Public Class Methods
The main class to instantiate the CircuitBraker class.
@example create a new breaker
breaker = CircuitBreaker::Redis.new do |cb| cb.circuit = -> (arg) { my_method(arg) } cb.failure_limit = 2 cb.reset_timeout = 5 cb.client = redis_client cb.namespace = "some_key" end
@yieldparam circuit - (look to {#circuit}) @yieldparam failure_limit
- (look to {#failure_limit}) @yieldparam reset_timeout
- (look to {#reset_timeout}) @yieldparam logger - (look to {#logger}) @yieldparam client - (look to {#client}) @yieldparam namespace - (look to {#namespace}) @return [CircuitBreaker::Redis] the object.
# File lib/circuit_breaker/redis.rb, line 48 def initialize yield self @client = client @namespace = namespace @failure_limit ||= 5 @reset_timeout ||= 10 @logger = Logger.new(STDOUT) run_validations @namespace = "circuit_breaker:#{namespace}" end
Public Instance Methods
# File lib/circuit_breaker/redis.rb, line 78 def add_failure(failure) client.sadd(fail_namespace, failure.to_json) end
failures= requires we replace what is currently in redis with the new value so we delete all entries first then add
# File lib/circuit_breaker/redis.rb, line 84 def failures=(failures) client.del(fail_namespace) failures.each { |f| client.sadd(fail_namespace, f.to_json) } end
# File lib/circuit_breaker/redis.rb, line 66 def state=(state) client.set(state_namespace, state.to_s) end
Private Instance Methods
# File lib/circuit_breaker/redis.rb, line 91 def fail_namespace "#{namespace}:failures" end
CircuitBreaker#run_validations
# File lib/circuit_breaker/redis.rb, line 99 def run_validations # call super to ensure module has what it needs super redis_commands = [:smembers, :get, :set, :sadd, :del] if !redis_commands.all? { |c| client.respond_to?(c) } raise NotImplementedError.new("Missing Methods. Your client must implement: #{redis_commands}") end if !namespace raise NotImplementedError.new("Missing namespace") end end
# File lib/circuit_breaker/redis.rb, line 95 def state_namespace "#{namespace}:state" end