Module: Faulty::Patch::Redis

Includes:
Base
Defined in:
lib/faulty/patch/redis.rb

Overview

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 circuit_from_hash for the available options.

Examples:

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 Also:

Defined Under Namespace

Classes: BusyError

Instance Method Summary collapse

Methods included from Base

#faulty_run

Instance Method Details

#call(command) ⇒ Object

Protect command calls


55
56
57
# File 'lib/faulty/patch/redis.rb', line 55

def call(command)
  faulty_run { super }
end

#call_loop(command, timeout = 0) ⇒ Object

Protect command_loop calls


60
61
62
# File 'lib/faulty/patch/redis.rb', line 60

def call_loop(command, timeout = 0)
  faulty_run { super }
end

#call_pipelined(commands) ⇒ Object

Protect pipelined commands


65
66
67
# File 'lib/faulty/patch/redis.rb', line 65

def call_pipelined(commands)
  faulty_run { super }
end

#connectObject

The initial connection is protected by a circuit


50
51
52
# File 'lib/faulty/patch/redis.rb', line 50

def connect
  faulty_run { super }
end

#initialize(options = {}) ⇒ Object

Patches Redis to add the :faulty key


35
36
37
38
39
40
41
42
43
44
45
46
47
# 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

#io(&block) ⇒ Object

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.


77
78
79
80
81
82
83
84
85
86
87
88
# 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