class CircuitBreaker::Redis

Attributes

circuit[RW]

(look to {CircuitBreaker::Memory#circuit})

client[RW]

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

failure_limit[RW]

(look to {CircuitBreaker::Memory#failure_limit})

failures[RW]

(look to {CircuitBreaker::Memory#failures})

logger[RW]

(look to {CircuitBreaker::Memory#logger})

namespace[RW]

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

reset_timeout[RW]

(look to {CircuitBreaker::Memory#reset_timeout})

state[RW]

(look to {CircuitBreaker::Memory#state})

Public Class Methods

new() { |self| ... } click to toggle source

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

add_failure(failure) click to toggle source
# File lib/circuit_breaker/redis.rb, line 78
def add_failure(failure)
  client.sadd(fail_namespace, failure.to_json)
end
failures=(failures) click to toggle source

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
state=(state) click to toggle source
# File lib/circuit_breaker/redis.rb, line 66
def state=(state)
  client.set(state_namespace, state.to_s)
end

Private Instance Methods

fail_namespace() click to toggle source
# File lib/circuit_breaker/redis.rb, line 91
def fail_namespace
  "#{namespace}:failures"
end
run_validations() click to toggle source
Calls superclass method 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
state_namespace() click to toggle source
# File lib/circuit_breaker/redis.rb, line 95
def state_namespace
  "#{namespace}:state"
end