lib/faulty/storage/interface.rb
# frozen_string_literal: true
class Faulty
module Storage
# The interface required for a storage backend implementation
#
# This is for documentation only and is not loaded
class Interface
# Get the options stored for circuit
#
# They should be returned exactly as given by {#set_options}
#
# @return [Hash] A hash of the options stored by {#set_options}. The keys
# must be symbols.
def get_options(circuit)
raise NotImplementedError
end
# Store the options for a circuit
#
# They should be returned exactly as given by {#set_options}
#
# @param circuit [Circuit] The circuit to set options for
# @param stored_options [Hash<Symbol, Object>] A hash of symbol option names to
# circuit options. These option values are guranteed to be primive
# values.
# @return [void]
def set_options(circuit, stored_options)
raise NotImplementedError
end
# Add a circuit run entry to storage
#
# The backend may choose to store this in whatever manner it chooses as
# long as it can implement the other read methods.
#
# @param circuit [Circuit] The circuit that ran
# @param time [Integer] The unix timestamp for the run
# @param success [Boolean] True if the run succeeded
# @param status [Status, nil] The previous status. If given, this method must
# return an updated status object from the new entry data.
# @return [Status, nil] If `status` is not nil, the updated status object.
def entry(circuit, time, success, status)
raise NotImplementedError
end
# Set the circuit state to open
#
# If multiple parallel processes open the circuit simultaneously, open
# may be called more than once. If so, this method should return true
# only once, when the circuit transitions from closed to open.
#
# If the backend does not support locking or atomic operations, then
# it may always return true, but that could result in duplicate open
# notifications.
#
# If returning true, this method also updates opened_at to the
# current time.
#
# @param circuit [Circuit] The circuit to open
# @param opened_at [Integer] The timestmp the circuit was opened at
# @return [Boolean] True if the circuit transitioned from closed to open
def open(circuit, opened_at)
raise NotImplementedError
end
# Reset the opened_at time for a half_open circuit
#
# If multiple parallel processes open the circuit simultaneously, reopen
# may be called more than once. If so, this method should return true
# only once, when the circuit updates the opened_at value. It can use the
# value from previous_opened_at to do a compare-and-set operation.
#
# If the backend does not support locking or atomic operations, then
# it may always return true, but that could result in duplicate reopen
# notifications.
#
# @param circuit [Circuit] The circuit to reopen
# @param opened_at [Integer] The timestmp the circuit was opened at
# @param previous_opened_at [Integer] The last known value of opened_at.
# Can be used to comare-and-set.
# @return [Boolean] True if the opened_at time was updated
def reopen(circuit, opened_at, previous_opened_at)
raise NotImplementedError
end
# Set the circuit state to closed
#
# If multiple parallel processes close the circuit simultaneously, close
# may be called more than once. If so, this method should return true
# only once, when the circuit transitions from open to closed.
#
# If the backend does not support locking or atomic operations, then
# it may always return true, but that could result in duplicate close
# notifications.
#
# @return [Boolean] True if the circuit transitioned from open to closed
def close(circuit)
raise NotImplementedError
end
# Lock the circuit in a given state
#
# No concurrency gurantees are provided for locking
#
# @param circuit [Circuit] The circuit to lock
# @param state [:open, :closed] The state to lock the circuit in
# @return [void]
def lock(circuit, state)
raise NotImplementedError
end
# Unlock the circuit from any state
#
# No concurrency gurantees are provided for locking
#
# @param circuit [Circuit] The circuit to unlock
# @return [void]
def unlock(circuit)
raise NotImplementedError
end
# Reset the circuit to a fresh state
#
# Clears all circuit status including entries, state, locks,
# opened_at, options, and any other values that would affect Status.
#
# No concurrency gurantees are provided for resetting
#
# @param circuit [Circuit] The circuit to unlock
# @return [void]
def reset(circuit)
raise NotImplementedError
end
# Get the status object for a circuit
#
# No concurrency gurantees are provided for getting status. It's possible
# that status may represent a circuit in the middle of modification.
#
# @param circuit [Circuit] The circuit to get status for
# @return [Status] The current status
def status(circuit)
raise NotImplementedError
end
# Get the entry history of a circuit
#
# No concurrency gurantees are provided for getting status. It's possible
# that status may represent a circuit in the middle of modification.
#
# A storage backend may choose not to implement this method and instead
# return an empty array.
#
# Each item in the history array is an array of two items (a tuple) of
# `[run_time, succeeded]`, where `run_time` is a unix timestamp, and
# `succeeded` is a boolean, true if the run succeeded.
#
# @param circuit [Circuit] The circuit to get history for
# @return [Array<Array>] An array of history tuples
def history(circuit)
raise NotImplementedError
end
# Get a list of all circuit names
#
# If the storage backend does not support listing circuits, this may
# return an empty array.
#
# @return [Array<String>]
def list
raise NotImplementedError
end
# Reset all circuits
#
# Some implementions may clear circuits on a best-effort basis since
# all circuits may not be known.
#
# @raise NotImplementedError If the storage backend does not support clearing.
# @return [void]
def clear
raise NotImplementedError
end
# Can this storage backend raise an error?
#
# If the storage backend returns false from this method, it will be wrapped
# in a {FaultTolerantProxy}, otherwise it will be used as-is.
#
# @return [Boolean] True if this cache backend is fault tolerant
def fault_tolerant?
raise NotImplementedError
end
end
end
end