Class: Faulty::Status
- Inherits:
-
Struct
- Object
- Struct
- Faulty::Status
- Includes:
- ImmutableOptions
- Defined in:
- lib/faulty/status.rb
Overview
The status of a circuit
Includes information like the state and locks. Also calculates whether a circuit can be run, or if it has failed a threshold.
Constant Summary collapse
- STATES =
The allowed state values
%i[ open closed ].freeze
- LOCKS =
The allowed lock values
%i[ open closed ].freeze
Instance Attribute Summary collapse
-
#failure_rate ⇒ Float
readonly
A number from 0 to 1 representing the percentage of failures for the circuit.
-
#lock ⇒ :open, ...
readonly
If the circuit is locked, the state that it is locked in.
-
#opened_at ⇒ Integer?
readonly
If the circuit is open, the timestamp that it was opened.
-
#options ⇒ Circuit::Options
readonly
The options for the circuit.
-
#sample_size ⇒ Integer
readonly
The number of samples used to calculate the failure rate.
-
#state ⇒ :open, :closed
readonly
The stored circuit state.
-
#stub ⇒ Boolean
readonly
True if this status is a stub and not calculated from the storage backend.
Class Method Summary collapse
-
.from_entries(entries, **hash) ⇒ Status
Create a new
Status
from a list of circuit runs.
Instance Method Summary collapse
-
#can_run? ⇒ Boolean
Whether the circuit can be run.
-
#closed? ⇒ Boolean
Whether the circuit is closed.
-
#fails_threshold? ⇒ Boolean
Whether the circuit fails the sample size and rate thresholds.
-
#half_open? ⇒ Boolean
Whether the circuit is half-open.
-
#locked_closed? ⇒ Boolean
Whether the circuit is locked closed.
-
#locked_open? ⇒ Boolean
Whether the circuit is locked open.
-
#open? ⇒ Boolean
Whether the circuit is open.
Methods included from ImmutableOptions
Instance Attribute Details
#failure_rate ⇒ Float (readonly)
Returns A number from 0 to 1 representing the percentage of failures for the circuit. For exmaple 0.5 represents a 50% failure rate.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/faulty/status.rb', line 33 Status = Struct.new( :state, :lock, :opened_at, :failure_rate, :sample_size, :options, :stub ) do include ImmutableOptions # The allowed state values STATES = %i[ open closed ].freeze # The allowed lock values LOCKS = %i[ open closed ].freeze # Create a new `Status` from a list of circuit runs # # For storage backends that store entries, this automatically calculates # failure_rate and sample size. # # @param entries [Array<Array>] An array of entry tuples. See # {Circuit#history} for details # @param hash [Hash] The status attributes minus failure_rate and # sample_size # @return [Status] def self.from_entries(entries, **hash) failures = 0 sample_size = 0 entries.each do |(time, success)| next unless time > Faulty.current_time - hash[:options].evaluation_window sample_size += 1 failures += 1 unless success end new(hash.merge( sample_size: sample_size, failure_rate: sample_size.zero? ? 0.0 : failures.to_f / sample_size )) end # Whether the circuit is open # # This is mutually exclusive with {#closed?} and {#half_open?} # # @return [Boolean] True if open def open? state == :open && opened_at + .cool_down > Faulty.current_time end # Whether the circuit is closed # # This is mutually exclusive with {#open?} and {#half_open?} # # @return [Boolean] True if closed def closed? state == :closed end # Whether the circuit is half-open # # This is mutually exclusive with {#open?} and {#closed?} # # @return [Boolean] True if half-open def half_open? state == :open && opened_at + .cool_down <= Faulty.current_time end # Whether the circuit is locked open # # @return [Boolean] True if locked open def locked_open? lock == :open end # Whether the circuit is locked closed # # @return [Boolean] True if locked closed def locked_closed? lock == :closed end # Whether the circuit can be run # # Takes the circuit state, locks and cooldown into account # # @return [Boolean] True if the circuit can be run def can_run? return false if locked_open? closed? || locked_closed? || half_open? end # Whether the circuit fails the sample size and rate thresholds # # @return [Boolean] True if the circuit fails the thresholds def fails_threshold? return false if sample_size < .sample_threshold failure_rate >= .rate_threshold end private def finalize raise ArgumentError, "state must be a symbol in #{self.class}::STATES" unless STATES.include?(state) unless lock.nil? || LOCKS.include?(state) raise ArgumentError, "lock must be a symbol in #{self.class}::LOCKS or nil" end end def required %i[state failure_rate sample_size options stub] end def defaults { state: :closed, failure_rate: 0.0, sample_size: 0, stub: false } end end |
#lock ⇒ :open, ... (readonly)
Returns If the circuit is locked, the state that
it is locked in. Default nil
.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/faulty/status.rb', line 33 Status = Struct.new( :state, :lock, :opened_at, :failure_rate, :sample_size, :options, :stub ) do include ImmutableOptions # The allowed state values STATES = %i[ open closed ].freeze # The allowed lock values LOCKS = %i[ open closed ].freeze # Create a new `Status` from a list of circuit runs # # For storage backends that store entries, this automatically calculates # failure_rate and sample size. # # @param entries [Array<Array>] An array of entry tuples. See # {Circuit#history} for details # @param hash [Hash] The status attributes minus failure_rate and # sample_size # @return [Status] def self.from_entries(entries, **hash) failures = 0 sample_size = 0 entries.each do |(time, success)| next unless time > Faulty.current_time - hash[:options].evaluation_window sample_size += 1 failures += 1 unless success end new(hash.merge( sample_size: sample_size, failure_rate: sample_size.zero? ? 0.0 : failures.to_f / sample_size )) end # Whether the circuit is open # # This is mutually exclusive with {#closed?} and {#half_open?} # # @return [Boolean] True if open def open? state == :open && opened_at + .cool_down > Faulty.current_time end # Whether the circuit is closed # # This is mutually exclusive with {#open?} and {#half_open?} # # @return [Boolean] True if closed def closed? state == :closed end # Whether the circuit is half-open # # This is mutually exclusive with {#open?} and {#closed?} # # @return [Boolean] True if half-open def half_open? state == :open && opened_at + .cool_down <= Faulty.current_time end # Whether the circuit is locked open # # @return [Boolean] True if locked open def locked_open? lock == :open end # Whether the circuit is locked closed # # @return [Boolean] True if locked closed def locked_closed? lock == :closed end # Whether the circuit can be run # # Takes the circuit state, locks and cooldown into account # # @return [Boolean] True if the circuit can be run def can_run? return false if locked_open? closed? || locked_closed? || half_open? end # Whether the circuit fails the sample size and rate thresholds # # @return [Boolean] True if the circuit fails the thresholds def fails_threshold? return false if sample_size < .sample_threshold failure_rate >= .rate_threshold end private def finalize raise ArgumentError, "state must be a symbol in #{self.class}::STATES" unless STATES.include?(state) unless lock.nil? || LOCKS.include?(state) raise ArgumentError, "lock must be a symbol in #{self.class}::LOCKS or nil" end end def required %i[state failure_rate sample_size options stub] end def defaults { state: :closed, failure_rate: 0.0, sample_size: 0, stub: false } end end |
#opened_at ⇒ Integer? (readonly)
Returns If the circuit is open, the timestamp that it was
opened. This is not necessarily reset when the circuit is closed.
Default nil
.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/faulty/status.rb', line 33 Status = Struct.new( :state, :lock, :opened_at, :failure_rate, :sample_size, :options, :stub ) do include ImmutableOptions # The allowed state values STATES = %i[ open closed ].freeze # The allowed lock values LOCKS = %i[ open closed ].freeze # Create a new `Status` from a list of circuit runs # # For storage backends that store entries, this automatically calculates # failure_rate and sample size. # # @param entries [Array<Array>] An array of entry tuples. See # {Circuit#history} for details # @param hash [Hash] The status attributes minus failure_rate and # sample_size # @return [Status] def self.from_entries(entries, **hash) failures = 0 sample_size = 0 entries.each do |(time, success)| next unless time > Faulty.current_time - hash[:options].evaluation_window sample_size += 1 failures += 1 unless success end new(hash.merge( sample_size: sample_size, failure_rate: sample_size.zero? ? 0.0 : failures.to_f / sample_size )) end # Whether the circuit is open # # This is mutually exclusive with {#closed?} and {#half_open?} # # @return [Boolean] True if open def open? state == :open && opened_at + .cool_down > Faulty.current_time end # Whether the circuit is closed # # This is mutually exclusive with {#open?} and {#half_open?} # # @return [Boolean] True if closed def closed? state == :closed end # Whether the circuit is half-open # # This is mutually exclusive with {#open?} and {#closed?} # # @return [Boolean] True if half-open def half_open? state == :open && opened_at + .cool_down <= Faulty.current_time end # Whether the circuit is locked open # # @return [Boolean] True if locked open def locked_open? lock == :open end # Whether the circuit is locked closed # # @return [Boolean] True if locked closed def locked_closed? lock == :closed end # Whether the circuit can be run # # Takes the circuit state, locks and cooldown into account # # @return [Boolean] True if the circuit can be run def can_run? return false if locked_open? closed? || locked_closed? || half_open? end # Whether the circuit fails the sample size and rate thresholds # # @return [Boolean] True if the circuit fails the thresholds def fails_threshold? return false if sample_size < .sample_threshold failure_rate >= .rate_threshold end private def finalize raise ArgumentError, "state must be a symbol in #{self.class}::STATES" unless STATES.include?(state) unless lock.nil? || LOCKS.include?(state) raise ArgumentError, "lock must be a symbol in #{self.class}::LOCKS or nil" end end def required %i[state failure_rate sample_size options stub] end def defaults { state: :closed, failure_rate: 0.0, sample_size: 0, stub: false } end end |
#options ⇒ Circuit::Options (readonly)
Returns The options for the circuit.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/faulty/status.rb', line 33 Status = Struct.new( :state, :lock, :opened_at, :failure_rate, :sample_size, :options, :stub ) do include ImmutableOptions # The allowed state values STATES = %i[ open closed ].freeze # The allowed lock values LOCKS = %i[ open closed ].freeze # Create a new `Status` from a list of circuit runs # # For storage backends that store entries, this automatically calculates # failure_rate and sample size. # # @param entries [Array<Array>] An array of entry tuples. See # {Circuit#history} for details # @param hash [Hash] The status attributes minus failure_rate and # sample_size # @return [Status] def self.from_entries(entries, **hash) failures = 0 sample_size = 0 entries.each do |(time, success)| next unless time > Faulty.current_time - hash[:options].evaluation_window sample_size += 1 failures += 1 unless success end new(hash.merge( sample_size: sample_size, failure_rate: sample_size.zero? ? 0.0 : failures.to_f / sample_size )) end # Whether the circuit is open # # This is mutually exclusive with {#closed?} and {#half_open?} # # @return [Boolean] True if open def open? state == :open && opened_at + .cool_down > Faulty.current_time end # Whether the circuit is closed # # This is mutually exclusive with {#open?} and {#half_open?} # # @return [Boolean] True if closed def closed? state == :closed end # Whether the circuit is half-open # # This is mutually exclusive with {#open?} and {#closed?} # # @return [Boolean] True if half-open def half_open? state == :open && opened_at + .cool_down <= Faulty.current_time end # Whether the circuit is locked open # # @return [Boolean] True if locked open def locked_open? lock == :open end # Whether the circuit is locked closed # # @return [Boolean] True if locked closed def locked_closed? lock == :closed end # Whether the circuit can be run # # Takes the circuit state, locks and cooldown into account # # @return [Boolean] True if the circuit can be run def can_run? return false if locked_open? closed? || locked_closed? || half_open? end # Whether the circuit fails the sample size and rate thresholds # # @return [Boolean] True if the circuit fails the thresholds def fails_threshold? return false if sample_size < .sample_threshold failure_rate >= .rate_threshold end private def finalize raise ArgumentError, "state must be a symbol in #{self.class}::STATES" unless STATES.include?(state) unless lock.nil? || LOCKS.include?(state) raise ArgumentError, "lock must be a symbol in #{self.class}::LOCKS or nil" end end def required %i[state failure_rate sample_size options stub] end def defaults { state: :closed, failure_rate: 0.0, sample_size: 0, stub: false } end end |
#sample_size ⇒ Integer (readonly)
Returns The number of samples used to calculate the failure rate.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/faulty/status.rb', line 33 Status = Struct.new( :state, :lock, :opened_at, :failure_rate, :sample_size, :options, :stub ) do include ImmutableOptions # The allowed state values STATES = %i[ open closed ].freeze # The allowed lock values LOCKS = %i[ open closed ].freeze # Create a new `Status` from a list of circuit runs # # For storage backends that store entries, this automatically calculates # failure_rate and sample size. # # @param entries [Array<Array>] An array of entry tuples. See # {Circuit#history} for details # @param hash [Hash] The status attributes minus failure_rate and # sample_size # @return [Status] def self.from_entries(entries, **hash) failures = 0 sample_size = 0 entries.each do |(time, success)| next unless time > Faulty.current_time - hash[:options].evaluation_window sample_size += 1 failures += 1 unless success end new(hash.merge( sample_size: sample_size, failure_rate: sample_size.zero? ? 0.0 : failures.to_f / sample_size )) end # Whether the circuit is open # # This is mutually exclusive with {#closed?} and {#half_open?} # # @return [Boolean] True if open def open? state == :open && opened_at + .cool_down > Faulty.current_time end # Whether the circuit is closed # # This is mutually exclusive with {#open?} and {#half_open?} # # @return [Boolean] True if closed def closed? state == :closed end # Whether the circuit is half-open # # This is mutually exclusive with {#open?} and {#closed?} # # @return [Boolean] True if half-open def half_open? state == :open && opened_at + .cool_down <= Faulty.current_time end # Whether the circuit is locked open # # @return [Boolean] True if locked open def locked_open? lock == :open end # Whether the circuit is locked closed # # @return [Boolean] True if locked closed def locked_closed? lock == :closed end # Whether the circuit can be run # # Takes the circuit state, locks and cooldown into account # # @return [Boolean] True if the circuit can be run def can_run? return false if locked_open? closed? || locked_closed? || half_open? end # Whether the circuit fails the sample size and rate thresholds # # @return [Boolean] True if the circuit fails the thresholds def fails_threshold? return false if sample_size < .sample_threshold failure_rate >= .rate_threshold end private def finalize raise ArgumentError, "state must be a symbol in #{self.class}::STATES" unless STATES.include?(state) unless lock.nil? || LOCKS.include?(state) raise ArgumentError, "lock must be a symbol in #{self.class}::LOCKS or nil" end end def required %i[state failure_rate sample_size options stub] end def defaults { state: :closed, failure_rate: 0.0, sample_size: 0, stub: false } end end |
#state ⇒ :open, :closed (readonly)
Returns The stored circuit state. This is always open
or closed. Half-open is calculated from the current time. For that
reason, calling state directly should be avoided. Instead use the
status methods #open?, #closed?, and #half_open?.
Default :closed
.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/faulty/status.rb', line 33 Status = Struct.new( :state, :lock, :opened_at, :failure_rate, :sample_size, :options, :stub ) do include ImmutableOptions # The allowed state values STATES = %i[ open closed ].freeze # The allowed lock values LOCKS = %i[ open closed ].freeze # Create a new `Status` from a list of circuit runs # # For storage backends that store entries, this automatically calculates # failure_rate and sample size. # # @param entries [Array<Array>] An array of entry tuples. See # {Circuit#history} for details # @param hash [Hash] The status attributes minus failure_rate and # sample_size # @return [Status] def self.from_entries(entries, **hash) failures = 0 sample_size = 0 entries.each do |(time, success)| next unless time > Faulty.current_time - hash[:options].evaluation_window sample_size += 1 failures += 1 unless success end new(hash.merge( sample_size: sample_size, failure_rate: sample_size.zero? ? 0.0 : failures.to_f / sample_size )) end # Whether the circuit is open # # This is mutually exclusive with {#closed?} and {#half_open?} # # @return [Boolean] True if open def open? state == :open && opened_at + .cool_down > Faulty.current_time end # Whether the circuit is closed # # This is mutually exclusive with {#open?} and {#half_open?} # # @return [Boolean] True if closed def closed? state == :closed end # Whether the circuit is half-open # # This is mutually exclusive with {#open?} and {#closed?} # # @return [Boolean] True if half-open def half_open? state == :open && opened_at + .cool_down <= Faulty.current_time end # Whether the circuit is locked open # # @return [Boolean] True if locked open def locked_open? lock == :open end # Whether the circuit is locked closed # # @return [Boolean] True if locked closed def locked_closed? lock == :closed end # Whether the circuit can be run # # Takes the circuit state, locks and cooldown into account # # @return [Boolean] True if the circuit can be run def can_run? return false if locked_open? closed? || locked_closed? || half_open? end # Whether the circuit fails the sample size and rate thresholds # # @return [Boolean] True if the circuit fails the thresholds def fails_threshold? return false if sample_size < .sample_threshold failure_rate >= .rate_threshold end private def finalize raise ArgumentError, "state must be a symbol in #{self.class}::STATES" unless STATES.include?(state) unless lock.nil? || LOCKS.include?(state) raise ArgumentError, "lock must be a symbol in #{self.class}::LOCKS or nil" end end def required %i[state failure_rate sample_size options stub] end def defaults { state: :closed, failure_rate: 0.0, sample_size: 0, stub: false } end end |
#stub ⇒ Boolean (readonly)
True if this status is a stub and not calculated from
the storage backend. Used by Faulty::Storage::FaultTolerantProxy when
returning the status for an offline storage backend. Default false
.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/faulty/status.rb', line 33 Status = Struct.new( :state, :lock, :opened_at, :failure_rate, :sample_size, :options, :stub ) do include ImmutableOptions # The allowed state values STATES = %i[ open closed ].freeze # The allowed lock values LOCKS = %i[ open closed ].freeze # Create a new `Status` from a list of circuit runs # # For storage backends that store entries, this automatically calculates # failure_rate and sample size. # # @param entries [Array<Array>] An array of entry tuples. See # {Circuit#history} for details # @param hash [Hash] The status attributes minus failure_rate and # sample_size # @return [Status] def self.from_entries(entries, **hash) failures = 0 sample_size = 0 entries.each do |(time, success)| next unless time > Faulty.current_time - hash[:options].evaluation_window sample_size += 1 failures += 1 unless success end new(hash.merge( sample_size: sample_size, failure_rate: sample_size.zero? ? 0.0 : failures.to_f / sample_size )) end # Whether the circuit is open # # This is mutually exclusive with {#closed?} and {#half_open?} # # @return [Boolean] True if open def open? state == :open && opened_at + .cool_down > Faulty.current_time end # Whether the circuit is closed # # This is mutually exclusive with {#open?} and {#half_open?} # # @return [Boolean] True if closed def closed? state == :closed end # Whether the circuit is half-open # # This is mutually exclusive with {#open?} and {#closed?} # # @return [Boolean] True if half-open def half_open? state == :open && opened_at + .cool_down <= Faulty.current_time end # Whether the circuit is locked open # # @return [Boolean] True if locked open def locked_open? lock == :open end # Whether the circuit is locked closed # # @return [Boolean] True if locked closed def locked_closed? lock == :closed end # Whether the circuit can be run # # Takes the circuit state, locks and cooldown into account # # @return [Boolean] True if the circuit can be run def can_run? return false if locked_open? closed? || locked_closed? || half_open? end # Whether the circuit fails the sample size and rate thresholds # # @return [Boolean] True if the circuit fails the thresholds def fails_threshold? return false if sample_size < .sample_threshold failure_rate >= .rate_threshold end private def finalize raise ArgumentError, "state must be a symbol in #{self.class}::STATES" unless STATES.include?(state) unless lock.nil? || LOCKS.include?(state) raise ArgumentError, "lock must be a symbol in #{self.class}::LOCKS or nil" end end def required %i[state failure_rate sample_size options stub] end def defaults { state: :closed, failure_rate: 0.0, sample_size: 0, stub: false } end end |
Class Method Details
.from_entries(entries, **hash) ⇒ Status
Create a new Status
from a list of circuit runs
For storage backends that store entries, this automatically calculates failure_rate and sample size.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/faulty/status.rb', line 66 def self.from_entries(entries, **hash) failures = 0 sample_size = 0 entries.each do |(time, success)| next unless time > Faulty.current_time - hash[:options].evaluation_window sample_size += 1 failures += 1 unless success end new(hash.merge( sample_size: sample_size, failure_rate: sample_size.zero? ? 0.0 : failures.to_f / sample_size )) end |
Instance Method Details
#can_run? ⇒ Boolean
Whether the circuit can be run
Takes the circuit state, locks and cooldown into account
128 129 130 131 132 |
# File 'lib/faulty/status.rb', line 128 def can_run? return false if locked_open? closed? || locked_closed? || half_open? end |
#closed? ⇒ Boolean
Whether the circuit is closed
This is mutually exclusive with #open? and #half_open?
96 97 98 |
# File 'lib/faulty/status.rb', line 96 def closed? state == :closed end |
#fails_threshold? ⇒ Boolean
Whether the circuit fails the sample size and rate thresholds
137 138 139 140 141 |
# File 'lib/faulty/status.rb', line 137 def fails_threshold? return false if sample_size < .sample_threshold failure_rate >= .rate_threshold end |
#half_open? ⇒ Boolean
105 106 107 |
# File 'lib/faulty/status.rb', line 105 def half_open? state == :open && opened_at + .cool_down <= Faulty.current_time end |
#locked_closed? ⇒ Boolean
Whether the circuit is locked closed
119 120 121 |
# File 'lib/faulty/status.rb', line 119 def locked_closed? lock == :closed end |
#locked_open? ⇒ Boolean
Whether the circuit is locked open
112 113 114 |
# File 'lib/faulty/status.rb', line 112 def locked_open? lock == :open end |
#open? ⇒ Boolean
Whether the circuit is open
This is mutually exclusive with #closed? and #half_open?
87 88 89 |
# File 'lib/faulty/status.rb', line 87 def open? state == :open && opened_at + .cool_down > Faulty.current_time end |