Class: Faulty::Storage::Memory

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

Overview

The default in-memory storage for circuits

This implementation is most suitable to single-process, low volume usage. It is thread-safe and circuit state is shared across threads.

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



72
73
74
75
# File 'lib/faulty/storage/memory.rb', line 72

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.



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

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:



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

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

#entry(circuit, time, success) ⇒ 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

Returns:

  • (Status)

    The circuit status after the run is added

See Also:



82
83
84
85
86
87
88
89
# File 'lib/faulty/storage/memory.rb', line 82

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

#fault_tolerant?true

Memory storage is fault-tolerant by default

Returns:

  • (true)


181
182
183
# File 'lib/faulty/storage/memory.rb', line 181

def fault_tolerant?
  true
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:



167
168
169
# File 'lib/faulty/storage/memory.rb', line 167

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

#listArray<String>

Get a list of circuit names

Returns:

  • (Array<String>)

    The circuit names



174
175
176
# File 'lib/faulty/storage/memory.rb', line 174

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:



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

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:



96
97
98
99
100
101
# File 'lib/faulty/storage/memory.rb', line 96

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:



108
109
110
111
# File 'lib/faulty/storage/memory.rb', line 108

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:



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

def reset(circuit)
  @circuits.delete(circuit.name)
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:



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

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:



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

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