Class: Stoplight::Infrastructure::Memory::DataStore
- Inherits:
-
Object
- Object
- Stoplight::Infrastructure::Memory::DataStore
show all
- Includes:
- MonitorMixin
- Defined in:
- lib/stoplight/infrastructure/memory/data_store.rb,
lib/stoplight/infrastructure/memory/data_store/state.rb,
lib/stoplight/infrastructure/memory/data_store/metrics.rb,
lib/stoplight/infrastructure/memory/data_store/sliding_window.rb,
lib/stoplight/infrastructure/memory/data_store/recovery_lock_store.rb,
lib/stoplight/infrastructure/memory/data_store/recovery_lock_token.rb
Overview
Defined Under Namespace
Classes: Metrics, RecoveryLockStore, RecoveryLockToken, SlidingWindow, State
Constant Summary
collapse
- KEY_SEPARATOR =
":"
Instance Method Summary
collapse
Constructor Details
#initialize(recovery_lock_store:, clock:) ⇒ DataStore
Returns a new instance of DataStore.
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 28
def initialize(recovery_lock_store:, clock:)
@clock = clock
@recovery_lock_store = recovery_lock_store
@errors = Hash.new { |errors, light_name| errors[light_name] = SlidingWindow.new(clock:) }
@successes = Hash.new { |successes, light_name| successes[light_name] = SlidingWindow.new(clock:) }
@metrics = Hash.new { |metrics, light_name| metrics[light_name] = Metrics.new }
@recovery_metrics = Hash.new { |metrics, light_name| metrics[light_name] = Metrics.new }
@states = Hash.new { |states, light_name| states[light_name] = State.new }
super() end
|
Instance Method Details
257
258
259
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 257
def acquire_recovery_lock(config)
recovery_lock_store.acquire_lock(config.name)
end
|
#clear_metrics(config) ⇒ Object
132
133
134
135
136
137
138
139
140
141
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 132
def clear_metrics(config)
light_name = config.name
synchronize do
if config.window_size
@errors[light_name] = SlidingWindow.new(clock:)
@successes[light_name] = SlidingWindow.new(clock:)
end
@metrics[light_name] = Metrics.new
end
end
|
#clear_recovery_metrics(config) ⇒ Object
143
144
145
146
147
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 143
def clear_recovery_metrics(config)
synchronize do
@recovery_metrics[config.name] = Metrics.new
end
end
|
#delete_light(config) ⇒ void
This method returns an undefined value.
225
226
227
228
229
230
231
232
233
234
235
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 225
def delete_light(config)
light_name = config.name
synchronize do
@states.delete(light_name)
@recovery_metrics.delete(light_name)
@metrics.delete(light_name)
@errors.delete(light_name)
@successes.delete(light_name)
end
end
|
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
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 49
def get_metrics(config)
light_name = config.name
synchronize do
current_time = clock.current_time
window_start = if config.window_size
(current_time - config.window_size)
else
current_time
end
metrics = @metrics[light_name]
errors = @errors[light_name].sum_in_window(window_start) if config.window_size
successes = @successes[light_name].sum_in_window(window_start) if config.window_size
consecutive_errors = config.window_size ? [metrics.consecutive_errors, errors].min : metrics.consecutive_errors
consecutive_successes = config.window_size ? [metrics.consecutive_successes.to_i, successes].min : metrics.consecutive_successes.to_i
Domain::MetricsSnapshot.new(
errors:,
successes:,
consecutive_errors:,
consecutive_successes:,
last_error: metrics.last_error,
last_success_at: metrics.last_success_at
)
end
end
|
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 79
def get_recovery_metrics(config)
light_name = config.name
synchronize do
metrics = @recovery_metrics[light_name]
Domain::MetricsSnapshot.new(
errors: nil, successes: nil,
consecutive_errors: metrics.consecutive_errors,
consecutive_successes: metrics.consecutive_successes,
last_error: metrics.last_error,
last_success_at: metrics.last_success_at
)
end
end
|
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 96
def get_state_snapshot(config)
time, state = synchronize do
[clock.current_time, @states[config.name]]
end
Domain::StateSnapshot.new(
time:,
locked_state: state.locked_state,
recovery_scheduled_after: state.recovery_scheduled_after,
recovery_started_at: state.recovery_started_at,
breached_at: state.breached_at
)
end
|
#inspect ⇒ String
219
220
221
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 219
def inspect
"#<#{self.class.name}>"
end
|
#names ⇒ Array<String>
43
44
45
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 43
def names
synchronize { @metrics.keys | @states.keys | @recovery_metrics.keys }
end
|
#record_failure(config, exception) ⇒ void
This method returns an undefined value.
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 113
def record_failure(config, exception)
current_time = clock.current_time
light_name = config.name
failure = Domain::Failure.from_error(exception, time: current_time)
synchronize do
@errors[light_name].increment if config.window_size
metrics = @metrics[light_name]
if metrics.last_error_at.nil? || failure.occurred_at > metrics.last_error_at
metrics.last_error = failure
end
metrics.consecutive_errors += 1
metrics.consecutive_successes = 0
end
end
|
#record_recovery_probe_failure(config, exception) ⇒ void
This method returns an undefined value.
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 172
def record_recovery_probe_failure(config, exception)
light_name = config.name
current_time = clock.current_time
failure = Domain::Failure.from_error(exception, time: current_time)
synchronize do
metrics = @recovery_metrics[light_name]
if metrics.last_error_at.nil? || failure.occurred_at > metrics.last_error_at
metrics.last_error = failure
end
metrics.consecutive_errors += 1
metrics.consecutive_successes = 0
end
end
|
#record_recovery_probe_success(config) ⇒ void
This method returns an undefined value.
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 191
def record_recovery_probe_success(config)
light_name = config.name
current_time = clock.current_time
synchronize do
metrics = @recovery_metrics[light_name]
if metrics.last_success_at.nil? || current_time > metrics.last_success_at
metrics.last_success_at = current_time
end
metrics.consecutive_errors = 0
metrics.consecutive_successes += 1
end
end
|
#record_success(config) ⇒ void
This method returns an undefined value.
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 151
def record_success(config)
light_name = config.name
current_time = clock.current_time
synchronize do
@successes[light_name].increment if config.window_size
metrics = @metrics[light_name]
if metrics.last_success_at.nil? || current_time > metrics.last_success_at
metrics.last_success_at = current_time
end
metrics.consecutive_errors = 0
metrics.consecutive_successes += 1
end
end
|
#release_recovery_lock(lock) ⇒ void
This method returns an undefined value.
263
264
265
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 263
def release_recovery_lock(lock)
recovery_lock_store.release_lock(lock)
end
|
#set_state(config, state) ⇒ String
209
210
211
212
213
214
215
216
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 209
def set_state(config, state)
light_name = config.name
synchronize do
@states[light_name].locked_state = state
end
state
end
|
#transition_to_color(config, color) ⇒ Boolean
Combined method that performs the state transition based on color
242
243
244
245
246
247
248
249
250
251
252
253
|
# File 'lib/stoplight/infrastructure/memory/data_store.rb', line 242
def transition_to_color(config, color)
case color
when Color::GREEN
transition_to_green(config)
when Color::YELLOW
transition_to_yellow(config)
when Color::RED
transition_to_red(config)
else
raise ArgumentError, "Invalid color: #{color}"
end
end
|