Class: Faulty::Storage::Memory

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

Overview

TODO:

Add a more sophsticated implmentation that can limit the number of circuits stored.

The default in-memory storage for circuits

This implementation is thread-safe and circuit state is shared across threads. Since state is stored in-memory, this state is not shared across processes, or persisted across application restarts.

Circuit state and runs are stored in memory. Although runs have a maximum size within a circuit, there is no limit on the number of circuits that can be stored. This means the user should be careful about the number of circuits that are created. To that end, it's a good idea to avoid dynamically-named circuits with this backend.

For a more robust distributed implementation, use the Redis storage backend.

This can be used as a reference implementation for storage backends that store a list of circuit run entries.

Defined Under Namespace

Classes: MemoryCircuit, Options

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**options) {|Options| ... } ⇒ Memory

Returns a new instance of Memory.

Parameters:

  • options (Hash)

    Attributes for Options

Yields:

  • (Options)

    For setting options in a block


74
75
76
77
# File 'lib/faulty/storage/memory.rb', line 74

def initialize(**options, &block)
  @circuits = Concurrent::Map.new
  @options = Options.new(options, &block)
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.


26
27
28
# File 'lib/faulty/storage/memory.rb', line 26

def options
  @options
end

Instance Method Details

#close(circuit) ⇒ Boolean

Mark a circuit as closed

Returns:

  • (Boolean)

    True if the circuit transitioned from open to closed

See Also:


138
139
140
141
142
# File 'lib/faulty/storage/memory.rb', line 138

def close(circuit)
  memory = fetch(circuit)
  memory.runs.modify { |_old| [] }
  memory.state.compare_and_set(:open, :closed)
end

#entry(circuit, time, success) ⇒ Array<Array>

Add an entry to storage

Parameters:

  • circuit (Circuit)

    The circuit that ran

  • time (Integer)

    The unix timestamp for the run

  • success (Boolean)

    True if the run succeeded

Returns:

  • (Array<Array>)

    An array of the new history tuples after adding the new entry, see #history

See Also:


102
103
104
105
106
107
108
109
# File 'lib/faulty/storage/memory.rb', line 102

def entry(circuit, time, success)
  memory = fetch(circuit)
  memory.runs.borrow do |runs|
    runs.push([time, success])
    runs.shift if runs.size > options.max_sample_size
  end
  memory.runs.value
end

#fault_tolerant?true

Memory storage is fault-tolerant by default

Returns:

  • (true)

201
202
203
# File 'lib/faulty/storage/memory.rb', line 201

def fault_tolerant?
  true
end

#get_options(circuit) ⇒ Hash

Get the options stored for circuit

Returns:

  • (Hash)

    A hash of the options stored by #set_options. The keys must be symbols.

See Also:


84
85
86
# File 'lib/faulty/storage/memory.rb', line 84

def get_options(circuit)
  fetch(circuit).options
end

#history(circuit) ⇒ Array<Array>

Get the circuit history up to max_sample_size

Parameters:

  • circuit (Circuit)

    The circuit to get history for

Returns:

  • (Array<Array>)

    An array of history tuples

See Also:


187
188
189
# File 'lib/faulty/storage/memory.rb', line 187

def history(circuit)
  fetch(circuit).runs.value
end

#listArray<String>

Get a list of circuit names

Returns:

  • (Array<String>)

    The circuit names


194
195
196
# File 'lib/faulty/storage/memory.rb', line 194

def list
  @circuits.keys
end

#lock(circuit, state) ⇒ void

This method returns an undefined value.

Lock a circuit open or closed

Parameters:

  • circuit (Circuit)

    The circuit to lock

  • state (:open, :closed)

    The state to lock the circuit in

See Also:


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

def lock(circuit, state)
  memory = fetch(circuit)
  memory.lock = state
end

#open(circuit, opened_at) ⇒ Boolean

Mark a circuit as open

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

See Also:


116
117
118
119
120
121
# File 'lib/faulty/storage/memory.rb', line 116

def open(circuit, opened_at)
  memory = fetch(circuit)
  opened = memory.state.compare_and_set(:closed, :open)
  memory.opened_at.reset(opened_at) if opened
  opened
end

#reopen(circuit, opened_at, previous_opened_at) ⇒ Boolean

Mark a circuit as reopened

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

See Also:


128
129
130
131
# File 'lib/faulty/storage/memory.rb', line 128

def reopen(circuit, opened_at, previous_opened_at)
  memory = fetch(circuit)
  memory.opened_at.compare_and_set(previous_opened_at, opened_at)
end

#reset(circuit) ⇒ void

This method returns an undefined value.

Reset a circuit

Parameters:

  • circuit (Circuit)

    The circuit to unlock

See Also:


169
170
171
# File 'lib/faulty/storage/memory.rb', line 169

def reset(circuit)
  @circuits.delete(circuit.name)
end

#set_options(circuit, stored_options) ⇒ void

This method returns an undefined value.

Store the options for a circuit

Parameters:

  • circuit (Circuit)

    The circuit to set options for

  • options (Hash<Symbol, Object>)

    A hash of symbol option names to circuit options. These option values are guranteed to be primive values.

See Also:


93
94
95
# File 'lib/faulty/storage/memory.rb', line 93

def set_options(circuit, stored_options)
  fetch(circuit).options = stored_options
end

#status(circuit) ⇒ Status

Get the status of a circuit

Parameters:

  • circuit (Circuit)

    The circuit to get status for

Returns:

  • (Status)

    The current status

See Also:


178
179
180
# File 'lib/faulty/storage/memory.rb', line 178

def status(circuit)
  fetch(circuit).status(circuit.options)
end

#unlock(circuit) ⇒ void

This method returns an undefined value.

Unlock a circuit

Parameters:

  • circuit (Circuit)

    The circuit to unlock

See Also:


159
160
161
162
# File 'lib/faulty/storage/memory.rb', line 159

def unlock(circuit)
  memory = fetch(circuit)
  memory.lock = nil
end