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

#clearvoid

This method returns an undefined value.

Clears all circuits



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

def clear
  @circuits.clear
end

#close(circuit) ⇒ Boolean

Mark a circuit as closed

Returns:

  • (Boolean)

    True if the circuit transitioned from open to closed

See Also:



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

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

#entry(circuit, time, success, status) ⇒ Status?

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

  • status (Status, nil)

    The previous status. If given, this method must return an updated status object from the new entry data.

Returns:

  • (Status, nil)

    If status is not nil, the updated status object.

See Also:



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

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

  Status.from_entries(memory.runs.value, **status.to_h) if status
end

#fault_tolerant?true

Memory storage is fault-tolerant by default

Returns:

  • (true)


209
210
211
# File 'lib/faulty/storage/memory.rb', line 209

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:



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

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

#listArray<String>

Get a list of circuit names

Returns:

  • (Array<String>)

    The circuit names



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

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:



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

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:



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

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:



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

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:



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

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

  • stored_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:



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

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:



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

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