Module: Faulty::Patch::Redis

Includes:
Base
Included in:
Redis::Client
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.

By default, all circuit errors raised by this patch inherit from ::Redis::BaseConnectionError

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



58
59
60
# File 'lib/faulty/patch/redis.rb', line 58

def call(command)
  faulty_run { super }
end

#call_loop(command, timeout = 0) ⇒ Object

Protect command_loop calls



63
64
65
# File 'lib/faulty/patch/redis.rb', line 63

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

#call_pipelined(commands) ⇒ Object

Protect pipelined commands



68
69
70
# File 'lib/faulty/patch/redis.rb', line 68

def call_pipelined(commands)
  faulty_run { super }
end

#connectObject

The initial connection is protected by a circuit



53
54
55
# File 'lib/faulty/patch/redis.rb', line 53

def connect
  faulty_run { super }
end

#initialize(options = {}) ⇒ Object

Patches Redis to add the :faulty key



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/faulty/patch/redis.rb', line 38

def initialize(options = {})
  @faulty_circuit = Patch.circuit_from_hash(
    'redis',
    options[:faulty],
    errors: [
      ::Redis::BaseConnectionError,
      BusyError
    ],
    patched_error_mapper: 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.



80
81
82
83
84
85
86
87
88
89
# File 'lib/faulty/patch/redis.rb', line 80

def io(&block)
  return super unless @faulty_circuit

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

  reply
end