Class: ResilientCall::Circuit
- Inherits:
-
Object
- Object
- ResilientCall::Circuit
- Defined in:
- lib/resilient_call/circuit.rb
Overview
Holds the state of a single named circuit and manages its transitions. Thread-safe: every public method runs under an internal Mutex.
closed --(threshold failures)--> open --(reset_timeout elapsed)--> half_open
^ |
+------------------------- record_success! -------------------------+
half_open --(record_failure!)--> open (restarts the timer)
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#reset_timeout ⇒ Object
readonly
Returns the value of attribute reset_timeout.
-
#threshold ⇒ Object
readonly
Returns the value of attribute threshold.
Instance Method Summary collapse
-
#allow_request? ⇒ Boolean
Whether a request may pass right now.
- #failure_count ⇒ Object
-
#initialize(name, threshold: 5, reset_timeout: 60) ⇒ Circuit
constructor
A new instance of Circuit.
- #last_failure ⇒ Object
- #opened_at ⇒ Object
- #record_failure!(error) ⇒ Object
- #record_success! ⇒ Object
- #reset! ⇒ Object
- #state ⇒ Object
-
#update_config(threshold: nil, reset_timeout: nil) ⇒ Object
Lets the entry point inject configured thresholds onto a circuit that was created lazily by the registry with default values.
Constructor Details
#initialize(name, threshold: 5, reset_timeout: 60) ⇒ Circuit
Returns a new instance of Circuit.
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/resilient_call/circuit.rb', line 14 def initialize(name, threshold: 5, reset_timeout: 60) @name = name @threshold = threshold @reset_timeout = reset_timeout @state = :closed @failure_count = 0 @opened_at = nil @last_failure = nil @mutex = Mutex.new end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
12 13 14 |
# File 'lib/resilient_call/circuit.rb', line 12 def name @name end |
#reset_timeout ⇒ Object (readonly)
Returns the value of attribute reset_timeout.
12 13 14 |
# File 'lib/resilient_call/circuit.rb', line 12 def reset_timeout @reset_timeout end |
#threshold ⇒ Object (readonly)
Returns the value of attribute threshold.
12 13 14 |
# File 'lib/resilient_call/circuit.rb', line 12 def threshold @threshold end |
Instance Method Details
#allow_request? ⇒ Boolean
Whether a request may pass right now. An :open circuit whose reset_timeout has elapsed transitions to :half_open and lets a single probe through.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/resilient_call/circuit.rb', line 43 def allow_request? @mutex.synchronize do case @state when :closed true when :half_open true when :open if Time.now - @opened_at >= @reset_timeout @state = :half_open true else false end end end end |
#failure_count ⇒ Object
29 30 31 |
# File 'lib/resilient_call/circuit.rb', line 29 def failure_count @mutex.synchronize { @failure_count } end |
#last_failure ⇒ Object
33 34 35 |
# File 'lib/resilient_call/circuit.rb', line 33 def last_failure @mutex.synchronize { @last_failure } end |
#opened_at ⇒ Object
37 38 39 |
# File 'lib/resilient_call/circuit.rb', line 37 def opened_at @mutex.synchronize { @opened_at } end |
#record_failure!(error) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/resilient_call/circuit.rb', line 73 def record_failure!(error) @mutex.synchronize do @failure_count += 1 @last_failure = error if @state == :half_open @state = :open @opened_at = Time.now elsif @state == :closed && @failure_count >= @threshold @state = :open @opened_at = Time.now end end end |
#record_success! ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/resilient_call/circuit.rb', line 61 def record_success! @mutex.synchronize do case @state when :half_open @state = :closed @failure_count = 0 when :closed @failure_count = 0 end end end |
#reset! ⇒ Object
88 89 90 91 92 93 94 95 |
# File 'lib/resilient_call/circuit.rb', line 88 def reset! @mutex.synchronize do @state = :closed @failure_count = 0 @opened_at = nil @last_failure = nil end end |
#state ⇒ Object
25 26 27 |
# File 'lib/resilient_call/circuit.rb', line 25 def state @mutex.synchronize { @state } end |
#update_config(threshold: nil, reset_timeout: nil) ⇒ Object
Lets the entry point inject configured thresholds onto a circuit that was created lazily by the registry with default values.
99 100 101 102 103 104 |
# File 'lib/resilient_call/circuit.rb', line 99 def update_config(threshold: nil, reset_timeout: nil) @mutex.synchronize do @threshold = threshold unless threshold.nil? @reset_timeout = reset_timeout unless reset_timeout.nil? end end |