stoplight 5.3.8 → 5.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +17 -2
- data/lib/generators/stoplight/install/templates/stoplight.rb.erb +2 -0
- data/lib/stoplight/admin/actions/remove.rb +23 -0
- data/lib/stoplight/admin/dependencies.rb +6 -1
- data/lib/stoplight/admin/helpers.rb +10 -5
- data/lib/stoplight/admin/lights_repository.rb +26 -14
- data/lib/stoplight/admin/views/_card.erb +13 -1
- data/lib/stoplight/admin/views/layout.erb +3 -3
- data/lib/stoplight/admin.rb +13 -4
- data/lib/stoplight/common/deprecations.rb +11 -0
- data/lib/stoplight/domain/color.rb +11 -0
- data/lib/stoplight/{config → domain}/compatibility_result.rb +1 -1
- data/lib/stoplight/domain/config.rb +59 -0
- data/lib/stoplight/{data_store/base.rb → domain/data_store.rb} +71 -17
- data/lib/stoplight/domain/error.rb +42 -0
- data/lib/stoplight/domain/failure.rb +44 -0
- data/lib/stoplight/domain/light/configuration_builder_interface.rb +234 -0
- data/lib/stoplight/domain/light.rb +208 -0
- data/lib/stoplight/domain/light_factory.rb +75 -0
- data/lib/stoplight/domain/metrics.rb +64 -0
- data/lib/stoplight/domain/recovery_lock_token.rb +15 -0
- data/lib/stoplight/domain/state.rb +11 -0
- data/lib/stoplight/domain/state_snapshot.rb +57 -0
- data/lib/stoplight/{notifier/base.rb → domain/state_transition_notifier.rb} +5 -4
- data/lib/stoplight/domain/storage/metrics.rb +42 -0
- data/lib/stoplight/domain/storage/recovery_lock.rb +56 -0
- data/lib/stoplight/domain/storage/state.rb +87 -0
- data/lib/stoplight/domain/strategies/green_run_strategy.rb +69 -0
- data/lib/stoplight/domain/strategies/red_run_strategy.rb +41 -0
- data/lib/stoplight/domain/strategies/run_strategy.rb +22 -0
- data/lib/stoplight/domain/strategies/yellow_run_strategy.rb +125 -0
- data/lib/stoplight/domain/tracker/base.rb +12 -0
- data/lib/stoplight/domain/tracker/recovery_probe.rb +76 -0
- data/lib/stoplight/domain/tracker/request.rb +72 -0
- data/lib/stoplight/domain/traffic_control/base.rb +74 -0
- data/lib/stoplight/domain/traffic_control/consecutive_errors.rb +53 -0
- data/lib/stoplight/domain/traffic_control/error_rate.rb +51 -0
- data/lib/stoplight/domain/traffic_recovery/base.rb +79 -0
- data/lib/stoplight/domain/traffic_recovery/consecutive_successes.rb +66 -0
- data/lib/stoplight/domain/traffic_recovery.rb +12 -0
- data/lib/stoplight/infrastructure/data_store/fail_safe.rb +164 -0
- data/lib/stoplight/infrastructure/data_store/memory/metrics.rb +27 -0
- data/lib/stoplight/infrastructure/data_store/memory/recovery_lock_store.rb +54 -0
- data/lib/stoplight/infrastructure/data_store/memory/recovery_lock_token.rb +20 -0
- data/lib/stoplight/infrastructure/data_store/memory/sliding_window.rb +79 -0
- data/lib/stoplight/infrastructure/data_store/memory/state.rb +21 -0
- data/lib/stoplight/infrastructure/data_store/memory.rb +338 -0
- data/lib/stoplight/infrastructure/data_store/redis/lua_scripts/get_metrics.lua +26 -0
- data/lib/stoplight/infrastructure/data_store/redis/lua_scripts/record_recovery_probe_failure.lua +27 -0
- data/lib/stoplight/infrastructure/data_store/redis/lua_scripts/record_recovery_probe_success.lua +23 -0
- data/lib/stoplight/infrastructure/data_store/redis/lua_scripts/release_lock.lua +6 -0
- data/lib/stoplight/infrastructure/data_store/redis/recovery_lock_store.rb +73 -0
- data/lib/stoplight/infrastructure/data_store/redis/recovery_lock_token.rb +35 -0
- data/lib/stoplight/infrastructure/data_store/redis/scripting.rb +71 -0
- data/lib/stoplight/infrastructure/data_store/redis.rb +524 -0
- data/lib/stoplight/infrastructure/notifier/fail_safe.rb +62 -0
- data/lib/stoplight/infrastructure/notifier/generic.rb +90 -0
- data/lib/stoplight/infrastructure/notifier/io.rb +23 -0
- data/lib/stoplight/infrastructure/notifier/logger.rb +21 -0
- data/lib/stoplight/infrastructure/storage/compatibility_metrics.rb +48 -0
- data/lib/stoplight/infrastructure/storage/compatibility_recovery_lock.rb +36 -0
- data/lib/stoplight/infrastructure/storage/compatibility_recovery_metrics.rb +55 -0
- data/lib/stoplight/infrastructure/storage/compatibility_state.rb +55 -0
- data/lib/stoplight/rspec/generic_notifier.rb +1 -1
- data/lib/stoplight/version.rb +1 -1
- data/lib/stoplight/wiring/data_store/base.rb +11 -0
- data/lib/stoplight/wiring/data_store/memory.rb +10 -0
- data/lib/stoplight/wiring/data_store/redis.rb +25 -0
- data/lib/stoplight/wiring/default.rb +28 -0
- data/lib/stoplight/{config/user_default_config.rb → wiring/default_configuration.rb} +24 -31
- data/lib/stoplight/wiring/default_factory_builder.rb +25 -0
- data/lib/stoplight/wiring/light/default_config.rb +18 -0
- data/lib/stoplight/wiring/light/system_config.rb +11 -0
- data/lib/stoplight/wiring/light_builder.rb +185 -0
- data/lib/stoplight/wiring/light_factory/compatibility_validator.rb +55 -0
- data/lib/stoplight/wiring/light_factory/config_normalizer.rb +71 -0
- data/lib/stoplight/wiring/light_factory/configuration_pipeline.rb +72 -0
- data/lib/stoplight/wiring/light_factory/traffic_control_dsl.rb +26 -0
- data/lib/stoplight/wiring/light_factory/traffic_recovery_dsl.rb +21 -0
- data/lib/stoplight/wiring/light_factory.rb +101 -0
- data/lib/stoplight/wiring/notifier_factory.rb +26 -0
- data/lib/stoplight/wiring/public_api.rb +29 -0
- data/lib/stoplight.rb +55 -30
- metadata +92 -42
- data/lib/stoplight/color.rb +0 -9
- data/lib/stoplight/config/dsl.rb +0 -97
- data/lib/stoplight/config/library_default_config.rb +0 -21
- data/lib/stoplight/config/system_config.rb +0 -7
- data/lib/stoplight/data_store/fail_safe.rb +0 -113
- data/lib/stoplight/data_store/memory.rb +0 -311
- data/lib/stoplight/data_store/redis/get_metadata.lua +0 -38
- data/lib/stoplight/data_store/redis/lua.rb +0 -23
- data/lib/stoplight/data_store/redis.rb +0 -449
- data/lib/stoplight/data_store.rb +0 -6
- data/lib/stoplight/default.rb +0 -30
- data/lib/stoplight/error.rb +0 -10
- data/lib/stoplight/failure.rb +0 -71
- data/lib/stoplight/light/config.rb +0 -111
- data/lib/stoplight/light/configuration_builder_interface.rb +0 -128
- data/lib/stoplight/light/green_run_strategy.rb +0 -54
- data/lib/stoplight/light/red_run_strategy.rb +0 -27
- data/lib/stoplight/light/run_strategy.rb +0 -32
- data/lib/stoplight/light/yellow_run_strategy.rb +0 -94
- data/lib/stoplight/light.rb +0 -191
- data/lib/stoplight/metadata.rb +0 -99
- data/lib/stoplight/notifier/fail_safe.rb +0 -70
- data/lib/stoplight/notifier/generic.rb +0 -79
- data/lib/stoplight/notifier/io.rb +0 -21
- data/lib/stoplight/notifier/logger.rb +0 -19
- data/lib/stoplight/state.rb +0 -9
- data/lib/stoplight/traffic_control/base.rb +0 -70
- data/lib/stoplight/traffic_control/consecutive_errors.rb +0 -55
- data/lib/stoplight/traffic_control/error_rate.rb +0 -49
- data/lib/stoplight/traffic_recovery/base.rb +0 -75
- data/lib/stoplight/traffic_recovery/consecutive_successes.rb +0 -68
- data/lib/stoplight/traffic_recovery.rb +0 -11
- /data/lib/stoplight/{data_store/redis → infrastructure/data_store/redis/lua_scripts}/record_failure.lua +0 -0
- /data/lib/stoplight/{data_store/redis → infrastructure/data_store/redis/lua_scripts}/record_success.lua +0 -0
- /data/lib/stoplight/{data_store/redis → infrastructure/data_store/redis/lua_scripts}/transition_to_green.lua +0 -0
- /data/lib/stoplight/{data_store/redis → infrastructure/data_store/redis/lua_scripts}/transition_to_red.lua +0 -0
- /data/lib/stoplight/{data_store/redis → infrastructure/data_store/redis/lua_scripts}/transition_to_yellow.lua +0 -0
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "monitor"
|
|
4
|
-
|
|
5
|
-
module Stoplight
|
|
6
|
-
module DataStore
|
|
7
|
-
# @see Base
|
|
8
|
-
class Memory < Base
|
|
9
|
-
include MonitorMixin
|
|
10
|
-
|
|
11
|
-
KEY_SEPARATOR = ":"
|
|
12
|
-
|
|
13
|
-
def initialize
|
|
14
|
-
@errors = Hash.new { |h, k| h[k] = [] }
|
|
15
|
-
@successes = Hash.new { |h, k| h[k] = [] }
|
|
16
|
-
|
|
17
|
-
@recovery_probe_errors = Hash.new { |h, k| h[k] = [] }
|
|
18
|
-
@recovery_probe_successes = Hash.new { |h, k| h[k] = [] }
|
|
19
|
-
|
|
20
|
-
@metadata = Hash.new { |h, k| h[k] = Metadata.new }
|
|
21
|
-
super # MonitorMixin
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# @return [Array<String>]
|
|
25
|
-
def names
|
|
26
|
-
synchronize { @metadata.keys }
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# @param config [Stoplight::Light::Config]
|
|
30
|
-
# @return [Stoplight::Metadata]
|
|
31
|
-
def get_metadata(config)
|
|
32
|
-
light_name = config.name
|
|
33
|
-
|
|
34
|
-
synchronize do
|
|
35
|
-
current_time = Time.now
|
|
36
|
-
recovery_window = (current_time - config.cool_off_time)..current_time
|
|
37
|
-
recovered_at = @metadata[light_name].recovered_at
|
|
38
|
-
window = if config.window_size
|
|
39
|
-
window_start = [recovered_at, (current_time - config.window_size)].compact.max
|
|
40
|
-
(window_start..current_time)
|
|
41
|
-
else
|
|
42
|
-
(..current_time)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
errors = @errors[config.name].count do |request_time|
|
|
46
|
-
window.cover?(request_time)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
successes = @successes[config.name].count do |request_time|
|
|
50
|
-
window.cover?(request_time)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
recovery_probe_errors = @recovery_probe_errors[config.name].count do |request_time|
|
|
54
|
-
recovery_window.cover?(request_time)
|
|
55
|
-
end
|
|
56
|
-
recovery_probe_successes = @recovery_probe_successes[config.name].count do |request_time|
|
|
57
|
-
recovery_window.cover?(request_time)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
@metadata[light_name].with(
|
|
61
|
-
current_time:,
|
|
62
|
-
errors:,
|
|
63
|
-
successes:,
|
|
64
|
-
recovery_probe_errors:,
|
|
65
|
-
recovery_probe_successes:
|
|
66
|
-
)
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# @param metrics [<Time>]
|
|
71
|
-
# @param window_size [Numeric, nil]
|
|
72
|
-
# @return [void]
|
|
73
|
-
def cleanup(metrics, window_size:)
|
|
74
|
-
min_age = Time.now - [window_size&.*(3), METRICS_RETENTION_TIME].compact.min
|
|
75
|
-
|
|
76
|
-
metrics.reject! { _1 < min_age }
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# @param config [Stoplight::Light::Config]
|
|
80
|
-
# @param failure [Stoplight::Failure]
|
|
81
|
-
# @return [Stoplight::Metadata]
|
|
82
|
-
def record_failure(config, failure)
|
|
83
|
-
light_name = config.name
|
|
84
|
-
|
|
85
|
-
synchronize do
|
|
86
|
-
@errors[light_name].unshift(failure.time) if config.window_size
|
|
87
|
-
|
|
88
|
-
cleanup(@errors[light_name], window_size: config.window_size)
|
|
89
|
-
|
|
90
|
-
metadata = @metadata[light_name]
|
|
91
|
-
@metadata[light_name] = if metadata.last_error_at.nil? || failure.time > metadata.last_error_at
|
|
92
|
-
metadata.with(
|
|
93
|
-
last_error_at: failure.time,
|
|
94
|
-
last_error: failure,
|
|
95
|
-
consecutive_errors: metadata.consecutive_errors.succ,
|
|
96
|
-
consecutive_successes: 0
|
|
97
|
-
)
|
|
98
|
-
else
|
|
99
|
-
metadata.with(
|
|
100
|
-
consecutive_errors: metadata.consecutive_errors.succ,
|
|
101
|
-
consecutive_successes: 0
|
|
102
|
-
)
|
|
103
|
-
end
|
|
104
|
-
get_metadata(config)
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# @param config [Stoplight::Light::Config]
|
|
109
|
-
# @param request_id [String]
|
|
110
|
-
# @param request_time [Time]
|
|
111
|
-
# @return [void]
|
|
112
|
-
def record_success(config, request_time: Time.now, request_id: SecureRandom.hex(12))
|
|
113
|
-
light_name = config.name
|
|
114
|
-
|
|
115
|
-
synchronize do
|
|
116
|
-
@successes[light_name].unshift(request_time) if config.window_size
|
|
117
|
-
cleanup(@successes[light_name], window_size: config.window_size)
|
|
118
|
-
|
|
119
|
-
metadata = @metadata[light_name]
|
|
120
|
-
@metadata[light_name] = if metadata.last_success_at.nil? || request_time > metadata.last_success_at
|
|
121
|
-
metadata.with(
|
|
122
|
-
last_success_at: request_time,
|
|
123
|
-
consecutive_errors: 0,
|
|
124
|
-
consecutive_successes: metadata.consecutive_successes.succ
|
|
125
|
-
)
|
|
126
|
-
else
|
|
127
|
-
metadata.with(
|
|
128
|
-
consecutive_errors: 0,
|
|
129
|
-
consecutive_successes: metadata.consecutive_successes.succ
|
|
130
|
-
)
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# @param config [Stoplight::Light::Config]
|
|
136
|
-
# @param failure [Stoplight::Failure]
|
|
137
|
-
# @return [Stoplight::Metadata]
|
|
138
|
-
def record_recovery_probe_failure(config, failure)
|
|
139
|
-
light_name = config.name
|
|
140
|
-
|
|
141
|
-
synchronize do
|
|
142
|
-
@recovery_probe_errors[light_name].unshift(failure.time)
|
|
143
|
-
cleanup(@recovery_probe_errors[light_name], window_size: config.cool_off_time)
|
|
144
|
-
|
|
145
|
-
metadata = @metadata[light_name]
|
|
146
|
-
@metadata[light_name] = if metadata.last_error_at.nil? || failure.time > metadata.last_error_at
|
|
147
|
-
metadata.with(
|
|
148
|
-
last_error_at: failure.time,
|
|
149
|
-
last_error: failure,
|
|
150
|
-
consecutive_errors: metadata.consecutive_errors.succ,
|
|
151
|
-
consecutive_successes: 0
|
|
152
|
-
)
|
|
153
|
-
else
|
|
154
|
-
metadata.with(
|
|
155
|
-
consecutive_errors: metadata.consecutive_errors.succ,
|
|
156
|
-
consecutive_successes: 0
|
|
157
|
-
)
|
|
158
|
-
end
|
|
159
|
-
get_metadata(config)
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
# @param config [Stoplight::Light::Config]
|
|
164
|
-
# @param request_id [String]
|
|
165
|
-
# @param request_time [Time]
|
|
166
|
-
# @return [Stoplight::Metadata]
|
|
167
|
-
def record_recovery_probe_success(config, request_time: Time.now, request_id: SecureRandom.hex(12))
|
|
168
|
-
light_name = config.name
|
|
169
|
-
|
|
170
|
-
synchronize do
|
|
171
|
-
@recovery_probe_successes[light_name].unshift(request_time)
|
|
172
|
-
cleanup(@recovery_probe_successes[light_name], window_size: config.cool_off_time)
|
|
173
|
-
|
|
174
|
-
metadata = @metadata[light_name]
|
|
175
|
-
@metadata[light_name] = if metadata.last_success_at.nil? || request_time > metadata.last_success_at
|
|
176
|
-
metadata.with(
|
|
177
|
-
last_success_at: request_time,
|
|
178
|
-
consecutive_errors: 0,
|
|
179
|
-
consecutive_successes: metadata.consecutive_successes.succ
|
|
180
|
-
)
|
|
181
|
-
else
|
|
182
|
-
metadata.with(
|
|
183
|
-
consecutive_errors: 0,
|
|
184
|
-
consecutive_successes: metadata.consecutive_successes.succ
|
|
185
|
-
)
|
|
186
|
-
end
|
|
187
|
-
get_metadata(config)
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
# @param config [Stoplight::Light::Config]
|
|
192
|
-
# @param state [String]
|
|
193
|
-
# @return [String]
|
|
194
|
-
def set_state(config, state)
|
|
195
|
-
light_name = config.name
|
|
196
|
-
|
|
197
|
-
synchronize do
|
|
198
|
-
metadata = @metadata[light_name]
|
|
199
|
-
@metadata[light_name] = metadata.with(locked_state: state)
|
|
200
|
-
end
|
|
201
|
-
state
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
# @return [String]
|
|
205
|
-
def inspect
|
|
206
|
-
"#<#{self.class.name}>"
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
# Combined method that performs the state transition based on color
|
|
210
|
-
#
|
|
211
|
-
# @param config [Stoplight::Light::Config] The light configuration
|
|
212
|
-
# @param color [String] The color to transition to ("GREEN", "YELLOW", or "RED")
|
|
213
|
-
# @param current_time [Time]
|
|
214
|
-
# @return [Boolean] true if this is the first instance to detect this transition
|
|
215
|
-
def transition_to_color(config, color, current_time: Time.now)
|
|
216
|
-
case color
|
|
217
|
-
when Color::GREEN
|
|
218
|
-
transition_to_green(config)
|
|
219
|
-
when Color::YELLOW
|
|
220
|
-
transition_to_yellow(config, current_time:)
|
|
221
|
-
when Color::RED
|
|
222
|
-
transition_to_red(config, current_time:)
|
|
223
|
-
else
|
|
224
|
-
raise ArgumentError, "Invalid color: #{color}"
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
# Transitions to GREEN state and ensures only one notification
|
|
229
|
-
#
|
|
230
|
-
# @param config [Stoplight::Light::Config] The light configuration
|
|
231
|
-
# @return [Boolean] true if this is the first instance to detect this transition
|
|
232
|
-
private def transition_to_green(config, current_time: Time.now)
|
|
233
|
-
light_name = config.name
|
|
234
|
-
|
|
235
|
-
synchronize do
|
|
236
|
-
metadata = @metadata[light_name]
|
|
237
|
-
if metadata.recovered_at
|
|
238
|
-
false
|
|
239
|
-
else
|
|
240
|
-
@metadata[light_name] = metadata.with(
|
|
241
|
-
recovered_at: current_time,
|
|
242
|
-
recovery_started_at: nil,
|
|
243
|
-
breached_at: nil,
|
|
244
|
-
recovery_scheduled_after: nil
|
|
245
|
-
)
|
|
246
|
-
true
|
|
247
|
-
end
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
# Transitions to YELLOW (recovery) state and ensures only one notification
|
|
252
|
-
#
|
|
253
|
-
# @param config [Stoplight::Light::Config] The light configuration
|
|
254
|
-
# @param current_time [Time]
|
|
255
|
-
# @return [Boolean] true if this is the first instance to detect this transition
|
|
256
|
-
private def transition_to_yellow(config, current_time: Time.now)
|
|
257
|
-
light_name = config.name
|
|
258
|
-
|
|
259
|
-
synchronize do
|
|
260
|
-
metadata = @metadata[light_name]
|
|
261
|
-
if metadata.recovery_started_at.nil?
|
|
262
|
-
@metadata[light_name] = metadata.with(
|
|
263
|
-
recovery_started_at: current_time,
|
|
264
|
-
recovery_scheduled_after: nil,
|
|
265
|
-
recovered_at: nil,
|
|
266
|
-
breached_at: nil
|
|
267
|
-
)
|
|
268
|
-
true
|
|
269
|
-
else
|
|
270
|
-
@metadata[light_name] = metadata.with(
|
|
271
|
-
recovery_scheduled_after: nil,
|
|
272
|
-
recovered_at: nil,
|
|
273
|
-
breached_at: nil
|
|
274
|
-
)
|
|
275
|
-
false
|
|
276
|
-
end
|
|
277
|
-
end
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
# Transitions to RED state and ensures only one notification
|
|
281
|
-
#
|
|
282
|
-
# @param config [Stoplight::Light::Config] The light configuration
|
|
283
|
-
# @param current_time [Time]
|
|
284
|
-
# @return [Boolean] true if this is the first instance to detect this transition
|
|
285
|
-
private def transition_to_red(config, current_time: Time.now)
|
|
286
|
-
light_name = config.name
|
|
287
|
-
recovery_scheduled_after = current_time + config.cool_off_time
|
|
288
|
-
|
|
289
|
-
synchronize do
|
|
290
|
-
metadata = @metadata[light_name]
|
|
291
|
-
if metadata.breached_at
|
|
292
|
-
@metadata[light_name] = metadata.with(
|
|
293
|
-
recovery_scheduled_after: recovery_scheduled_after,
|
|
294
|
-
recovery_started_at: nil,
|
|
295
|
-
recovered_at: nil
|
|
296
|
-
)
|
|
297
|
-
false
|
|
298
|
-
else
|
|
299
|
-
@metadata[light_name] = metadata.with(
|
|
300
|
-
breached_at: current_time,
|
|
301
|
-
recovery_scheduled_after: recovery_scheduled_after,
|
|
302
|
-
recovery_started_at: nil,
|
|
303
|
-
recovered_at: nil
|
|
304
|
-
)
|
|
305
|
-
true
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
end
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
local number_of_metric_buckets = tonumber(ARGV[1])
|
|
2
|
-
local number_of_recovery_buckets = tonumber(ARGV[2])
|
|
3
|
-
local window_start_ts = tonumber(ARGV[3])
|
|
4
|
-
local window_end_ts = tonumber(ARGV[4])
|
|
5
|
-
local recovery_window_start_ts = tonumber(ARGV[5])
|
|
6
|
-
|
|
7
|
-
local metadata_key = KEYS[1]
|
|
8
|
-
|
|
9
|
-
-- It possible that after a successful recovery, Stoplight still see metrics
|
|
10
|
-
-- that are older than the recovery window. To prevent this from happening,
|
|
11
|
-
-- we need to limit the start time of the window to the time of the last recovery.
|
|
12
|
-
local recovered_at = redis.call('HGET', metadata_key, "recovered_at")
|
|
13
|
-
if recovered_at then
|
|
14
|
-
window_start_ts = math.max(window_start_ts, tonumber(recovered_at))
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
local function count_events(start_idx, bucket_count, start_ts)
|
|
18
|
-
local total = 0
|
|
19
|
-
for idx = start_idx, start_idx + bucket_count - 1 do
|
|
20
|
-
total = total + tonumber(redis.call('ZCOUNT', KEYS[idx], start_ts, window_end_ts))
|
|
21
|
-
end
|
|
22
|
-
return total
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
local offset = 2
|
|
26
|
-
local successes = count_events(2, number_of_metric_buckets, window_start_ts)
|
|
27
|
-
|
|
28
|
-
offset = offset + number_of_metric_buckets
|
|
29
|
-
local errors = count_events(offset, number_of_metric_buckets, window_start_ts)
|
|
30
|
-
|
|
31
|
-
offset = offset + number_of_metric_buckets
|
|
32
|
-
local recovery_probe_successes = count_events(offset, number_of_recovery_buckets, recovery_window_start_ts)
|
|
33
|
-
|
|
34
|
-
offset = offset + number_of_recovery_buckets
|
|
35
|
-
local recovery_probe_errors = count_events(offset, number_of_recovery_buckets, recovery_window_start_ts)
|
|
36
|
-
|
|
37
|
-
local metadata = redis.call('HGETALL', metadata_key)
|
|
38
|
-
return {successes, errors, recovery_probe_successes, recovery_probe_errors, metadata}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module DataStore
|
|
5
|
-
class Redis
|
|
6
|
-
# @api private
|
|
7
|
-
module Lua
|
|
8
|
-
class << self
|
|
9
|
-
def read_lua_file(name_without_extension)
|
|
10
|
-
File.read(File.join(__dir__, "#{name_without_extension}.lua"))
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
RECORD_FAILURE = read_lua_file("record_failure")
|
|
15
|
-
RECORD_SUCCESS = read_lua_file("record_success")
|
|
16
|
-
GET_METADATA = read_lua_file("get_metadata")
|
|
17
|
-
TRANSITION_TO_YELLOW = read_lua_file("transition_to_yellow")
|
|
18
|
-
TRANSITION_TO_RED = read_lua_file("transition_to_red")
|
|
19
|
-
TRANSITION_TO_GREEN = read_lua_file("transition_to_green")
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|