Class: Stoplight::Infrastructure::Memory::Storage::State
- Inherits:
-
Object
- Object
- Stoplight::Infrastructure::Memory::Storage::State
- Includes:
- Domain::_StateStore
- Defined in:
- lib/stoplight/infrastructure/memory/storage/state.rb,
sig/_private/stoplight/infrastructure/memory/storage/state.rbs
Overview
Thread-safe in-memory state storage for a single light.
Manages light state transitions and ensures notification deduplication through atomic transition detection. Each transition method returns whether the calling thread was first to trigger that transition, enabling exactly-once notification semantics.
Instance Attribute Summary collapse
-
#breached_at ⇒ Time?
Returns the value of attribute breached_at.
-
#clock ⇒ Domain::_Clock
readonly
Returns the value of attribute clock.
-
#cool_off_time ⇒ timestamp
readonly
Returns the value of attribute cool_off_time.
-
#locked_state ⇒ state
Returns the value of attribute locked_state.
-
#mutex ⇒ Mutex
readonly
Returns the value of attribute mutex.
-
#recovered_at ⇒ Time?
Returns the value of attribute recovered_at.
-
#recovery_scheduled_after ⇒ Time?
Returns the value of attribute recovery_scheduled_after.
-
#recovery_started_at ⇒ Time?
Returns the value of attribute recovery_started_at.
Instance Method Summary collapse
- #clear ⇒ Object
-
#initialize(clock:, cool_off_time:) ⇒ State
constructor
A new instance of State.
- #set_state(state) ⇒ Object
- #state_snapshot ⇒ Object
-
#transition_to_color(color) ⇒ Object
Combined method that performs the state transition based on color.
-
#transition_to_green ⇒ Object
Transitions to GREEN state and ensures only one notification.
-
#transition_to_red ⇒ Object
Transitions to RED state and ensures only one notification.
-
#transition_to_yellow ⇒ Object
Transitions to YELLOW (recovery) state and ensures only one notification.
Constructor Details
#initialize(clock:, cool_off_time:) ⇒ State
Returns a new instance of State.
32 33 34 35 36 37 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 32 def initialize(clock:, cool_off_time:) @locked_state = Stoplight::State::UNLOCKED @mutex = Thread::Mutex.new @clock = clock @cool_off_time = cool_off_time end |
Instance Attribute Details
#breached_at ⇒ Time?
Returns the value of attribute breached_at.
90 91 92 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 90 def breached_at @breached_at end |
#clock ⇒ Domain::_Clock (readonly)
Returns the value of attribute clock.
92 93 94 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 92 def clock @clock end |
#cool_off_time ⇒ timestamp (readonly)
Returns the value of attribute cool_off_time.
93 94 95 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 93 def cool_off_time @cool_off_time end |
#locked_state ⇒ state
Returns the value of attribute locked_state.
86 87 88 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 86 def locked_state @locked_state end |
#mutex ⇒ Mutex (readonly)
Returns the value of attribute mutex.
91 92 93 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 91 def mutex @mutex end |
#recovered_at ⇒ Time?
Returns the value of attribute recovered_at.
87 88 89 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 87 def recovered_at @recovered_at end |
#recovery_scheduled_after ⇒ Time?
Returns the value of attribute recovery_scheduled_after.
88 89 90 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 88 def recovery_scheduled_after @recovery_scheduled_after end |
#recovery_started_at ⇒ Time?
Returns the value of attribute recovery_started_at.
89 90 91 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 89 def recovery_started_at @recovery_started_at end |
Instance Method Details
#clear ⇒ Object
74 75 76 77 78 79 80 81 82 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 74 def clear mutex.synchronize do self.locked_state = Stoplight::State::UNLOCKED self.recovered_at = nil self.recovery_scheduled_after = nil self.breached_at = nil self.recovery_started_at = nil end end |
#set_state(state) ⇒ Object
39 40 41 42 43 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 39 def set_state(state) mutex.synchronize do self.locked_state = state end end |
#state_snapshot ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 45 def state_snapshot mutex.synchronize do Domain::StateSnapshot.new( time: clock.current_time, locked_state:, recovery_scheduled_after:, recovery_started_at:, breached_at: ) end end |
#transition_to_color(color) ⇒ Object
Combined method that performs the state transition based on color
61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 61 def transition_to_color(color) case color when Color::GREEN transition_to_green when Color::YELLOW transition_to_yellow when Color::RED transition_to_red else raise ArgumentError, "Invalid color: #{color}" end end |
#transition_to_green ⇒ Object
Transitions to GREEN state and ensures only one notification
98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 98 def transition_to_green mutex.synchronize do if recovered_at false else self.recovered_at = clock.current_time self.recovery_started_at = nil self.breached_at = nil self.recovery_scheduled_after = nil true end end end |
#transition_to_red ⇒ Object
Transitions to RED state and ensures only one notification
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 135 def transition_to_red mutex.synchronize do current_time = clock.current_time self.recovery_scheduled_after = current_time + cool_off_time self.recovery_started_at = nil self.recovered_at = nil if breached_at false else self.breached_at = current_time true end end end |
#transition_to_yellow ⇒ Object
Transitions to YELLOW (recovery) state and ensures only one notification
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/stoplight/infrastructure/memory/storage/state.rb', line 115 def transition_to_yellow mutex.synchronize do if recovery_started_at.nil? self.recovery_started_at = clock.current_time self.recovery_scheduled_after = nil self.recovered_at = nil self.breached_at = nil true else self.recovery_scheduled_after = nil self.recovered_at = nil self.breached_at = nil false end end end |