Class: Faulty::Storage::FallbackChain

Inherits:
Object
  • Object
show all
Defined in:
lib/faulty/storage/fallback_chain.rb

Overview

An prioritized list of storage backends

If any backend fails, the next will be tried until one succeeds. This should typically be used when using a fault-prone backend such as Redis.

This is used by Faulty#initialize if the storage option is set to an array.

Examples:

# This storage will try Redis first, then fallback to memory storage
# if Redis is unavailable.
storage = Faulty::Storage::FallbackChain.new([
  Faulty::Storage::Redis.new,
  Faulty::Storage::Memory.new
])

Defined Under Namespace

Classes: Options

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(storages, **options) {|Options| ... } ⇒ FallbackChain

Create a new Faulty::Storage::FallbackChain to automatically fallback to reliable storage

Parameters:

  • storages (Array<Storage::Interface>)

    An array of storage backends. The primary storage should be specified first. If that one fails, additional entries will be tried in sequence until one succeeds.

  • options (Hash)

    Attributes for Options

Yields:

  • (Options)

    For setting options in a block


47
48
49
50
# File 'lib/faulty/storage/fallback_chain.rb', line 47

def initialize(storages, **options, &block)
  @storages = storages
  @options = Options.new(options, &block)
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options


22
23
24
# File 'lib/faulty/storage/fallback_chain.rb', line 22

def options
  @options
end

Instance Method Details

#close(circuit) ⇒ Boolean

Close a circuit in the first available storage backend

Returns:

  • (Boolean)

    True if the circuit transitioned from open to closed


86
87
88
89
90
# File 'lib/faulty/storage/fallback_chain.rb', line 86

def close(circuit)
  send_chain(:close, circuit) do |e|
    options.notifier.notify(:storage_failure, circuit: circuit, action: :close, error: e)
  end
end

#entry(circuit, time, success) ⇒ Status

Create a circuit entry in the first available storage backend

Parameters:

  • circuit (Circuit)

    The circuit that ran

  • time (Integer)

    The unix timestamp for the run

  • success (Boolean)

    True if the run succeeded

Returns:

  • (Status)

    The circuit status after the run is added


56
57
58
59
60
# File 'lib/faulty/storage/fallback_chain.rb', line 56

def entry(circuit, time, success)
  send_chain(:entry, circuit, time, success) do |e|
    options.notifier.notify(:storage_failure, circuit: circuit, action: :entry, error: e)
  end
end

#fault_tolerant?Boolean

This is fault tolerant if any of the available backends are fault tolerant

Returns:

  • (Boolean)

    True if this cache backend is fault tolerant


150
151
152
# File 'lib/faulty/storage/fallback_chain.rb', line 150

def fault_tolerant?
  @storages.any?(&:fault_tolerant?)
end

#history(circuit) ⇒ Array<Array>

Get the history of a circuit from the first available storage backend

Parameters:

  • circuit (Circuit)

    The circuit to get history for

Returns:

  • (Array<Array>)

    An array of history tuples


130
131
132
133
134
# File 'lib/faulty/storage/fallback_chain.rb', line 130

def history(circuit)
  send_chain(:history, circuit) do |e|
    options.notifier.notify(:storage_failure, circuit: circuit, action: :history, error: e)
  end
end

#listArray<String>

Get the list of circuits from the first available storage backend

Returns:

  • (Array<String>)

140
141
142
143
144
# File 'lib/faulty/storage/fallback_chain.rb', line 140

def list
  send_chain(:list) do |e|
    options.notifier.notify(:storage_failure, action: :list, error: e)
  end
end

#lock(circuit, state) ⇒ void

This method returns an undefined value.

Lock a circuit in all storage backends

Parameters:

  • circuit (Circuit)

    The circuit to lock

  • state (:open, :closed)

    The state to lock the circuit in


96
97
98
# File 'lib/faulty/storage/fallback_chain.rb', line 96

def lock(circuit, state)
  send_all(:lock, circuit, state)
end

#open(circuit, opened_at) ⇒ Boolean

Open a circuit in the first available storage backend

Parameters:

  • circuit (Circuit)

    The circuit to open

  • opened_at (Integer)

    The timestmp the circuit was opened at

Returns:

  • (Boolean)

    True if the circuit transitioned from closed to open


66
67
68
69
70
# File 'lib/faulty/storage/fallback_chain.rb', line 66

def open(circuit, opened_at)
  send_chain(:open, circuit, opened_at) do |e|
    options.notifier.notify(:storage_failure, circuit: circuit, action: :open, error: e)
  end
end

#reopen(circuit, opened_at, previous_opened_at) ⇒ Boolean

Reopen a circuit in the first available storage backend

Parameters:

  • circuit (Circuit)

    The circuit to reopen

  • opened_at (Integer)

    The timestmp the circuit was opened at

  • previous_opened_at (Integer)

    The last known value of opened_at. Can be used to comare-and-set.

Returns:

  • (Boolean)

    True if the opened_at time was updated


76
77
78
79
80
# File 'lib/faulty/storage/fallback_chain.rb', line 76

def reopen(circuit, opened_at, previous_opened_at)
  send_chain(:reopen, circuit, opened_at, previous_opened_at) do |e|
    options.notifier.notify(:storage_failure, circuit: circuit, action: :reopen, error: e)
  end
end

#reset(circuit) ⇒ void

This method returns an undefined value.

Reset a circuit in all storage backends

Parameters:

  • circuit (Circuit)

    The circuit to unlock


112
113
114
# File 'lib/faulty/storage/fallback_chain.rb', line 112

def reset(circuit)
  send_all(:reset, circuit)
end

#status(circuit) ⇒ Status

Get the status of a circuit from the first available storage backend

Parameters:

  • circuit (Circuit)

    The circuit to get status for

Returns:

  • (Status)

    The current status


120
121
122
123
124
# File 'lib/faulty/storage/fallback_chain.rb', line 120

def status(circuit)
  send_chain(:status, circuit) do |e|
    options.notifier.notify(:storage_failure, circuit: circuit, action: :status, error: e)
  end
end

#unlock(circuit) ⇒ void

This method returns an undefined value.

Unlock a circuit in all storage backends

Parameters:

  • circuit (Circuit)

    The circuit to unlock


104
105
106
# File 'lib/faulty/storage/fallback_chain.rb', line 104

def unlock(circuit)
  send_all(:unlock, circuit)
end