module Faulty::Patch::Redis

Patch Redis to run all network IO in a circuit

This module is not required by default

Pass a `:faulty` key into your MySQL connection options to enable circuit protection. See {Patch.circuit_from_hash} for the available options.

@example

require 'faulty/patch/redis'

redis = Redis.new(url: 'redis://localhost:6379', faulty: {})
redis.connect # raises Faulty::CircuitError if connection fails

# If the faulty key is not given, no circuit is used
redis = Redis.new(url: 'redis://localhost:6379')
redis.connect # not protected by a circuit

@see Patch.circuit_from_hash

Public Class Methods

new(options = {}) click to toggle source

Patches Redis to add the `:faulty` key

Calls superclass method
# File lib/faulty/patch/redis.rb, line 35
def initialize(options = {})
  @faulty_circuit = Patch.circuit_from_hash(
    'redis',
    options[:faulty],
    errors: [
      ::Redis::BaseConnectionError,
      BusyError
    ],
    patched_error_module: Faulty::Patch::Redis
  )

  super
end

Public Instance Methods

call(command) click to toggle source

Protect command calls

Calls superclass method
# File lib/faulty/patch/redis.rb, line 55
def call(command)
  faulty_run { super }
end
call_loop(command, timeout = 0) click to toggle source

Protect command_loop calls

Calls superclass method
# File lib/faulty/patch/redis.rb, line 60
def call_loop(command, timeout = 0)
  faulty_run { super }
end
call_pipelined(commands) click to toggle source

Protect pipelined commands

Calls superclass method
# File lib/faulty/patch/redis.rb, line 65
def call_pipelined(commands)
  faulty_run { super }
end
connect() click to toggle source

The initial connection is protected by a circuit

Calls superclass method
# File lib/faulty/patch/redis.rb, line 50
def connect
  faulty_run { super }
end
io(&block) click to toggle source

Inject specific error classes if client is patched

This method does not raise errors, it returns them as exception objects, so we simply modify that error if necessary and return it.

The call* methods above will then raise that error, so we are able to capture it with faulty_run.

Calls superclass method
# File lib/faulty/patch/redis.rb, line 77
def io(&block)
  return super unless @faulty_circuit

  reply = super
  if reply.is_a?(::Redis::CommandError)
    if reply.message.start_with?('BUSY')
      reply = BusyError.new(reply.message)
    end
  end

  reply
end