stoplight 5.8.3 → 6.0.0.rc2

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.
Files changed (323) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/LICENSE.md +1 -0
  4. data/README.md +132 -79
  5. data/UPGRADING.md +265 -6
  6. data/lib/stoplight/admin/actions/action.rb +4 -12
  7. data/lib/stoplight/admin/actions/lock.rb +12 -9
  8. data/lib/stoplight/admin/actions/lock_all.rb +27 -0
  9. data/lib/stoplight/admin/actions/remove.rb +12 -9
  10. data/lib/stoplight/admin/actions/stats.rb +15 -12
  11. data/lib/stoplight/admin/actions/unlock.rb +10 -9
  12. data/lib/stoplight/admin/assets/apple-touch-icon.png +0 -0
  13. data/lib/stoplight/admin/assets/favicon.ico +0 -0
  14. data/lib/stoplight/admin/assets/flowbite.min.css +2 -0
  15. data/lib/stoplight/admin/assets/flowbite.min.js +1 -0
  16. data/lib/stoplight/admin/assets/icon.svg +7 -0
  17. data/lib/stoplight/admin/assets/turbo.es2017-esm.min.js +34 -0
  18. data/lib/stoplight/admin/config_registry.rb +40 -0
  19. data/lib/stoplight/admin/dependencies.rb +29 -28
  20. data/lib/stoplight/admin/helpers.rb +50 -17
  21. data/lib/stoplight/admin/light_view.rb +184 -0
  22. data/lib/stoplight/admin/lights_stats.rb +7 -9
  23. data/lib/stoplight/admin/views/_card.erb +19 -21
  24. data/lib/stoplight/admin/views/index.erb +9 -3
  25. data/lib/stoplight/admin/views/layout.erb +45 -13
  26. data/lib/stoplight/admin.rb +110 -21
  27. data/lib/stoplight/data_store.rb +18 -8
  28. data/lib/stoplight/domain/config.rb +4 -1
  29. data/lib/stoplight/domain/error_tracking_policy.rb +9 -0
  30. data/lib/stoplight/domain/failure.rb +4 -0
  31. data/lib/stoplight/domain/id.rb +13 -0
  32. data/lib/stoplight/domain/light.rb +35 -77
  33. data/lib/stoplight/domain/lock_control.rb +55 -0
  34. data/lib/stoplight/domain/matcher_validator.rb +24 -0
  35. data/lib/stoplight/domain/state_snapshot.rb +2 -6
  36. data/lib/stoplight/domain/strategies/green_run_strategy.rb +33 -19
  37. data/lib/stoplight/domain/strategies/red_run_strategy.rb +8 -2
  38. data/lib/stoplight/domain/strategies/yellow_run_strategy.rb +56 -32
  39. data/lib/stoplight/domain/telemetry/bus.rb +90 -0
  40. data/lib/stoplight/domain/telemetry/consumer.rb +18 -0
  41. data/lib/stoplight/domain/telemetry/emitter.rb +45 -0
  42. data/lib/stoplight/domain/telemetry/envelope.rb +15 -0
  43. data/lib/stoplight/domain/telemetry/failure.rb +13 -0
  44. data/lib/stoplight/domain/telemetry/light_registered.rb +12 -0
  45. data/lib/stoplight/domain/telemetry/lock_changed.rb +19 -0
  46. data/lib/stoplight/domain/telemetry/metrics.rb +15 -0
  47. data/lib/stoplight/domain/telemetry/recovery_failed.rb +20 -0
  48. data/lib/stoplight/domain/telemetry/recovery_probe_completed.rb +15 -0
  49. data/lib/stoplight/domain/telemetry/recovery_started.rb +18 -0
  50. data/lib/stoplight/domain/telemetry/recovery_succeeded.rb +19 -0
  51. data/lib/stoplight/domain/telemetry/run_completed.rb +17 -0
  52. data/lib/stoplight/domain/telemetry/run_recorder.rb +58 -0
  53. data/lib/stoplight/domain/telemetry/settings.rb +21 -0
  54. data/lib/stoplight/domain/telemetry/state_transitioned.rb +11 -0
  55. data/lib/stoplight/domain/telemetry/subscription.rb +11 -0
  56. data/lib/stoplight/domain/telemetry/traffic_breached.rb +20 -0
  57. data/lib/stoplight/domain/tracker/recovery_probe.rb +61 -17
  58. data/lib/stoplight/domain/tracker/request.rb +17 -8
  59. data/lib/stoplight/domain/traffic_control/consecutive_errors.rb +13 -3
  60. data/lib/stoplight/domain/traffic_control/error_rate.rb +16 -12
  61. data/lib/stoplight/domain/traffic_recovery/consecutive_successes.rb +9 -3
  62. data/lib/stoplight/error.rb +10 -1
  63. data/lib/stoplight/infrastructure/config_serializer.rb +50 -0
  64. data/lib/stoplight/infrastructure/fail_safe/error_notifier.rb +25 -0
  65. data/lib/stoplight/infrastructure/fail_safe/storage/registry.rb +68 -0
  66. data/lib/stoplight/infrastructure/memory/storage/registry.rb +18 -0
  67. data/lib/stoplight/infrastructure/memory/storage/unbounded_metrics.rb +29 -32
  68. data/lib/stoplight/infrastructure/memory/storage/window_metrics/sliding_window.rb +74 -0
  69. data/lib/stoplight/infrastructure/memory/storage/window_metrics.rb +25 -24
  70. data/lib/stoplight/infrastructure/notifier/fail_safe.rb +3 -8
  71. data/lib/stoplight/infrastructure/notifier/generic.rb +3 -3
  72. data/lib/stoplight/infrastructure/redis/key.rb +25 -0
  73. data/lib/stoplight/infrastructure/redis/storage/now.lua +9 -0
  74. data/lib/stoplight/infrastructure/redis/storage/recovery_lock.rb +2 -4
  75. data/lib/stoplight/infrastructure/redis/storage/recovery_metrics.rb +1 -1
  76. data/lib/stoplight/infrastructure/redis/storage/registry.rb +73 -0
  77. data/lib/stoplight/infrastructure/redis/storage/scripting.rb +54 -3
  78. data/lib/stoplight/infrastructure/redis/storage/state/transition_to_green.lua +3 -1
  79. data/lib/stoplight/infrastructure/redis/storage/state/transition_to_red.lua +4 -2
  80. data/lib/stoplight/infrastructure/redis/storage/state/transition_to_yellow.lua +3 -1
  81. data/lib/stoplight/infrastructure/redis/storage/state.rb +8 -8
  82. data/lib/stoplight/infrastructure/redis/storage/unbounded_metrics/record_failure.lua +20 -21
  83. data/lib/stoplight/infrastructure/redis/storage/unbounded_metrics/record_success.lua +11 -19
  84. data/lib/stoplight/infrastructure/redis/storage/unbounded_metrics.rb +20 -16
  85. data/lib/stoplight/infrastructure/redis/storage/window_metrics/_evict.lua +44 -0
  86. data/lib/stoplight/infrastructure/redis/storage/window_metrics/metrics_snapshot.lua +14 -21
  87. data/lib/stoplight/infrastructure/redis/storage/window_metrics/record_failure.lua +38 -36
  88. data/lib/stoplight/infrastructure/redis/storage/window_metrics/record_success.lua +23 -30
  89. data/lib/stoplight/infrastructure/redis/storage/window_metrics.rb +45 -135
  90. data/lib/stoplight/infrastructure/system_clock.rb +4 -0
  91. data/lib/stoplight/telemetry.rb +19 -0
  92. data/lib/stoplight/types.rb +15 -2
  93. data/lib/stoplight/version.rb +1 -1
  94. data/lib/stoplight/wiring/config_compatibility_validator.rb +25 -2
  95. data/lib/stoplight/wiring/default.rb +1 -1
  96. data/lib/stoplight/wiring/default_config.rb +2 -1
  97. data/lib/stoplight/wiring/default_configuration.rb +3 -2
  98. data/lib/stoplight/wiring/external_caller.rb +27 -0
  99. data/lib/stoplight/wiring/fail_safe_config.rb +11 -0
  100. data/lib/stoplight/wiring/global_state.rb +93 -0
  101. data/lib/stoplight/wiring/{light_factory → light_configuration_dsl}/traffic_control_dsl.rb +3 -5
  102. data/lib/stoplight/wiring/{light_factory → light_configuration_dsl}/traffic_recovery_dsl.rb +2 -2
  103. data/lib/stoplight/wiring/light_configuration_dsl.rb +97 -0
  104. data/lib/stoplight/wiring/light_factory.rb +154 -97
  105. data/lib/stoplight/wiring/notifier_bridge.rb +33 -0
  106. data/lib/stoplight/wiring/redis/backend.rb +1 -1
  107. data/lib/stoplight/wiring/system/storage.rb +69 -0
  108. data/lib/stoplight/wiring/system.rb +125 -56
  109. data/lib/stoplight/wiring/{configuration_dsl.rb → system_configuration_dsl.rb} +13 -43
  110. data/lib/stoplight.rb +50 -194
  111. data/sig/sinatra/base.rbs +6 -0
  112. data/sig/stdlib/securerandom.rbs +4 -0
  113. data/sig/stoplight/admin/actions/action.rbs +10 -0
  114. data/sig/stoplight/admin/actions/lock.rbs +17 -0
  115. data/sig/stoplight/admin/actions/lock_all.rbs +17 -0
  116. data/sig/stoplight/admin/actions/remove.rbs +22 -0
  117. data/sig/stoplight/admin/actions/stats.rbs +28 -0
  118. data/sig/stoplight/admin/actions/unlock.rbs +17 -0
  119. data/sig/stoplight/admin/config_registry.rbs +20 -0
  120. data/sig/stoplight/admin/dependencies.rbs +16 -0
  121. data/sig/stoplight/admin/helpers.rbs +17 -0
  122. data/sig/stoplight/admin/light_view.rbs +39 -0
  123. data/sig/stoplight/admin/lights_stats.rbs +30 -0
  124. data/sig/stoplight/admin.rbs +14 -0
  125. data/sig/stoplight/color.rbs +3 -3
  126. data/sig/{_private/stoplight/data_store.rbs → stoplight/data_store/base.rbs} +1 -0
  127. data/sig/stoplight/data_store/memory.rbs +9 -0
  128. data/sig/stoplight/data_store/redis.rbs +17 -0
  129. data/sig/{_private/stoplight → stoplight}/domain/config.rbs +28 -24
  130. data/sig/{_private/stoplight → stoplight}/domain/error_tracking_policy.rbs +4 -0
  131. data/sig/{_private/stoplight → stoplight}/domain/failure.rbs +2 -0
  132. data/sig/stoplight/domain/id.rbs +7 -0
  133. data/sig/stoplight/domain/light.rbs +39 -0
  134. data/sig/{_private/stoplight → stoplight}/domain/light_info.rbs +1 -5
  135. data/sig/stoplight/domain/lock_control.rbs +16 -0
  136. data/sig/stoplight/domain/matcher_validator.rbs +11 -0
  137. data/sig/{_private/stoplight → stoplight}/domain/ports/clock.rbs +6 -0
  138. data/sig/stoplight/domain/ports/data_store.rbs +9 -0
  139. data/sig/stoplight/domain/ports/error_notifier.rbs +12 -0
  140. data/sig/stoplight/domain/ports/exception_matcher.rbs +10 -0
  141. data/sig/{_private/stoplight → stoplight}/domain/ports/metrics_store.rbs +2 -2
  142. data/sig/stoplight/domain/ports/registry.rbs +13 -0
  143. data/sig/{_private/stoplight → stoplight}/domain/ports/run_strategy.rbs +2 -1
  144. data/sig/stoplight/domain/ports/state_transition_notifier.rbs +18 -0
  145. data/sig/stoplight/domain/ports/telemetry.rbs +28 -0
  146. data/sig/stoplight/domain/ports/telemetry_publisher.rbs +14 -0
  147. data/sig/{_private/stoplight → stoplight}/domain/ports/traffic_control.rbs +7 -0
  148. data/sig/{_private/stoplight → stoplight}/domain/ports/traffic_recovery.rbs +2 -3
  149. data/sig/stoplight/domain/strategies/green_run_strategy.rbs +22 -0
  150. data/sig/stoplight/domain/strategies/red_run_strategy.rbs +19 -0
  151. data/sig/{_private/stoplight → stoplight}/domain/strategies/yellow_run_strategy.rbs +23 -12
  152. data/sig/stoplight/domain/telemetry/bus.rbs +49 -0
  153. data/sig/stoplight/domain/telemetry/consumer.rbs +13 -0
  154. data/sig/stoplight/domain/telemetry/emitter.rbs +51 -0
  155. data/sig/stoplight/domain/telemetry/envelope.rbs +30 -0
  156. data/sig/stoplight/domain/telemetry/failure.rbs +23 -0
  157. data/sig/stoplight/domain/telemetry/light_registered.rbs +23 -0
  158. data/sig/stoplight/domain/telemetry/lock_changed.rbs +31 -0
  159. data/sig/stoplight/domain/telemetry/metrics.rbs +27 -0
  160. data/sig/stoplight/domain/telemetry/recovery_failed.rbs +36 -0
  161. data/sig/stoplight/domain/telemetry/recovery_probe_completed.rbs +29 -0
  162. data/sig/stoplight/domain/telemetry/recovery_started.rbs +26 -0
  163. data/sig/stoplight/domain/telemetry/recovery_succeeded.rbs +31 -0
  164. data/sig/stoplight/domain/telemetry/run_completed.rbs +38 -0
  165. data/sig/stoplight/domain/telemetry/run_recorder.rbs +27 -0
  166. data/sig/stoplight/domain/telemetry/settings.rbs +47 -0
  167. data/sig/stoplight/domain/telemetry/state_transitioned.rbs +11 -0
  168. data/sig/stoplight/domain/telemetry/subscription.rbs +9 -0
  169. data/sig/stoplight/domain/telemetry/traffic_breached.rbs +36 -0
  170. data/sig/stoplight/domain/telemetry/types.rbs +32 -0
  171. data/sig/{_private/stoplight → stoplight}/domain/tracker/recovery_probe.rbs +10 -6
  172. data/sig/{_private/stoplight → stoplight}/domain/tracker/request.rbs +3 -3
  173. data/sig/{_private/stoplight → stoplight}/domain/traffic_control/consecutive_errors.rbs +2 -0
  174. data/sig/{_private/stoplight → stoplight}/domain/traffic_control/error_rate.rbs +3 -2
  175. data/sig/{_private/stoplight → stoplight}/domain/traffic_recovery/consecutive_successes.rbs +2 -0
  176. data/sig/stoplight/domain/types.rbs +25 -0
  177. data/sig/stoplight/error.rbs +8 -0
  178. data/sig/stoplight/generators/rails_generators_base.rbs +11 -0
  179. data/sig/stoplight/infrastructure/config_serializer.rbs +12 -0
  180. data/sig/stoplight/infrastructure/fail_safe/error_notifier.rbs +13 -0
  181. data/sig/{_private/stoplight → stoplight}/infrastructure/fail_safe/storage/metrics.rbs +2 -2
  182. data/sig/{_private/stoplight → stoplight}/infrastructure/fail_safe/storage/recovery_lock.rbs +2 -2
  183. data/sig/stoplight/infrastructure/fail_safe/storage/registry.rbs +23 -0
  184. data/sig/{_private/stoplight → stoplight}/infrastructure/fail_safe/storage/state.rbs +4 -4
  185. data/sig/stoplight/infrastructure/memory/storage/registry.rbs +13 -0
  186. data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/state.rbs +3 -3
  187. data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/unbounded_metrics.rbs +7 -7
  188. data/sig/stoplight/infrastructure/memory/storage/window_metrics/sliding_window.rbs +27 -0
  189. data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/window_metrics.rbs +7 -7
  190. data/sig/stoplight/infrastructure/notifier/fail_safe.rbs +15 -0
  191. data/sig/{_private/stoplight → stoplight}/infrastructure/notifier/generic.rbs +1 -1
  192. data/sig/{_private/stoplight → stoplight}/infrastructure/notifier/io.rbs +1 -1
  193. data/sig/{_private/stoplight → stoplight}/infrastructure/notifier/logger.rbs +1 -1
  194. data/sig/stoplight/infrastructure/redis/key.rbs +10 -0
  195. data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/recovery_lock.rbs +2 -2
  196. data/sig/stoplight/infrastructure/redis/storage/registry.rbs +27 -0
  197. data/sig/stoplight/infrastructure/redis/storage/scripting.rbs +34 -0
  198. data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/state.rbs +4 -4
  199. data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/unbounded_metrics.rbs +8 -1
  200. data/sig/stoplight/infrastructure/redis/storage/window_metrics.rbs +35 -0
  201. data/sig/stoplight/infrastructure/types.rbs +6 -0
  202. data/sig/stoplight/notifier.rbs +1 -1
  203. data/sig/stoplight/ports/system.rbs +16 -10
  204. data/sig/stoplight/state.rbs +3 -3
  205. data/sig/stoplight/telemetry.rbs +17 -0
  206. data/sig/stoplight/types.rbs +9 -0
  207. data/sig/{_private/stoplight → stoplight}/wiring/config_compatibility_validator.rbs +2 -0
  208. data/sig/stoplight/wiring/default.rbs +26 -0
  209. data/sig/stoplight/wiring/default_configuration.rbs +39 -0
  210. data/sig/stoplight/wiring/external_caller.rbs +13 -0
  211. data/sig/stoplight/wiring/fail_safe_config.rbs +7 -0
  212. data/sig/stoplight/wiring/global_state.rbs +36 -0
  213. data/sig/{_private/stoplight/wiring/light_factory → stoplight/wiring/light_configuration_dsl}/traffic_control_dsl.rbs +1 -1
  214. data/sig/{_private/stoplight/wiring/light_factory → stoplight/wiring/light_configuration_dsl}/traffic_recovery_dsl.rbs +1 -1
  215. data/sig/stoplight/wiring/light_configuration_dsl.rbs +38 -0
  216. data/sig/stoplight/wiring/light_factory.rbs +78 -0
  217. data/sig/stoplight/wiring/notifier_bridge.rbs +15 -0
  218. data/sig/stoplight/wiring/notifier_factory.rbs +10 -0
  219. data/sig/{_private/stoplight → stoplight}/wiring/redis/backend.rbs +6 -6
  220. data/sig/stoplight/wiring/system/storage.rbs +35 -0
  221. data/sig/stoplight/wiring/system.rbs +30 -0
  222. data/sig/stoplight/wiring/system_configuration_dsl.rbs +39 -0
  223. data/sig/stoplight/wiring/types.rbs +6 -0
  224. data/sig/stoplight.rbs +37 -54
  225. metadata +190 -143
  226. data/lib/stoplight/admin/actions/lock_all_green.rb +0 -18
  227. data/lib/stoplight/admin/actions/lock_green.rb +0 -23
  228. data/lib/stoplight/admin/actions/lock_red.rb +0 -23
  229. data/lib/stoplight/admin/lights_repository/light.rb +0 -171
  230. data/lib/stoplight/admin/lights_repository.rb +0 -87
  231. data/lib/stoplight/domain/light/configuration_builder_interface.rb +0 -236
  232. data/lib/stoplight/infrastructure/fail_safe/data_store.rb +0 -152
  233. data/lib/stoplight/infrastructure/memory/data_store/metrics.rb +0 -27
  234. data/lib/stoplight/infrastructure/memory/data_store/recovery_lock_store.rb +0 -52
  235. data/lib/stoplight/infrastructure/memory/data_store/recovery_lock_token.rb +0 -17
  236. data/lib/stoplight/infrastructure/memory/data_store/sliding_window.rb +0 -74
  237. data/lib/stoplight/infrastructure/memory/data_store/state.rb +0 -21
  238. data/lib/stoplight/infrastructure/memory/data_store.rb +0 -342
  239. data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/get_metrics.lua +0 -26
  240. data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_failure.lua +0 -36
  241. data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_recovery_probe_failure.lua +0 -27
  242. data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_recovery_probe_success.lua +0 -23
  243. data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_success.lua +0 -35
  244. data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/release_lock.lua +0 -6
  245. data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/transition_to_green.lua +0 -10
  246. data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/transition_to_red.lua +0 -10
  247. data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/transition_to_yellow.lua +0 -9
  248. data/lib/stoplight/infrastructure/redis/data_store/recovery_lock_store.rb +0 -60
  249. data/lib/stoplight/infrastructure/redis/data_store/recovery_lock_token.rb +0 -28
  250. data/lib/stoplight/infrastructure/redis/data_store/scripting.rb +0 -73
  251. data/lib/stoplight/infrastructure/redis/data_store.rb +0 -516
  252. data/lib/stoplight/infrastructure/redis/storage/key_space.rb +0 -51
  253. data/lib/stoplight/infrastructure/storage/compatibility_metrics.rb +0 -41
  254. data/lib/stoplight/infrastructure/storage/compatibility_recovery_lock.rb +0 -33
  255. data/lib/stoplight/infrastructure/storage/compatibility_recovery_metrics.rb +0 -47
  256. data/lib/stoplight/infrastructure/storage/compatibility_state.rb +0 -44
  257. data/lib/stoplight/wiring/light_builder.rb +0 -198
  258. data/lib/stoplight/wiring/notifier_factory.rb +0 -26
  259. data/lib/stoplight/wiring/system/light_builder.rb +0 -47
  260. data/lib/stoplight/wiring/system/light_factory.rb +0 -64
  261. data/sig/_private/stoplight/domain/light.rbs +0 -25
  262. data/sig/_private/stoplight/domain/ports/data_store.rbs +0 -76
  263. data/sig/_private/stoplight/domain/ports/light_factory.rbs +0 -80
  264. data/sig/_private/stoplight/domain/strategies/green_run_strategy.rbs +0 -17
  265. data/sig/_private/stoplight/domain/strategies/red_run_strategy.rbs +0 -17
  266. data/sig/_private/stoplight/domain/tracker/base.rbs +0 -8
  267. data/sig/_private/stoplight/infrastructure/fail_safe/data_store.rbs +0 -26
  268. data/sig/_private/stoplight/infrastructure/memory/data_store/metrics.rbs +0 -25
  269. data/sig/_private/stoplight/infrastructure/memory/data_store/recovery_lock_store.rbs +0 -19
  270. data/sig/_private/stoplight/infrastructure/memory/data_store/recovery_lock_token.rbs +0 -17
  271. data/sig/_private/stoplight/infrastructure/memory/data_store/sliding_window.rbs +0 -27
  272. data/sig/_private/stoplight/infrastructure/memory/data_store/state.rbs +0 -17
  273. data/sig/_private/stoplight/infrastructure/memory/data_store.rbs +0 -30
  274. data/sig/_private/stoplight/infrastructure/notifier/fail_safe.rbs +0 -17
  275. data/sig/_private/stoplight/infrastructure/redis/data_store/recovery_lock_store.rbs +0 -24
  276. data/sig/_private/stoplight/infrastructure/redis/data_store/recovery_lock_token.rbs +0 -21
  277. data/sig/_private/stoplight/infrastructure/redis/data_store/scripting.rbs +0 -34
  278. data/sig/_private/stoplight/infrastructure/redis/data_store.rbs +0 -67
  279. data/sig/_private/stoplight/infrastructure/redis/storage/key_space.rbs +0 -19
  280. data/sig/_private/stoplight/infrastructure/redis/storage/scripting.rbs +0 -13
  281. data/sig/_private/stoplight/infrastructure/redis/storage/window_metrics.rbs +0 -34
  282. data/sig/_private/stoplight/infrastructure/storage/compatibility_metrics.rbs +0 -17
  283. data/sig/_private/stoplight/infrastructure/storage/compatibility_recovery_lock.rbs +0 -13
  284. data/sig/_private/stoplight/infrastructure/storage/compatibility_recovery_metrics.rbs +0 -14
  285. data/sig/_private/stoplight/infrastructure/storage/compatibility_state.rbs +0 -14
  286. data/sig/_private/stoplight/system/light_builder.rbs +0 -23
  287. data/sig/_private/stoplight/system/light_factory.rbs +0 -17
  288. data/sig/_private/stoplight/types.rbs +0 -6
  289. data/sig/_private/stoplight/wiring/configuration_dsl.rbs +0 -43
  290. data/sig/_private/stoplight/wiring/default.rbs +0 -26
  291. data/sig/_private/stoplight/wiring/default_configuration.rbs +0 -29
  292. data/sig/_private/stoplight/wiring/light_builder.rbs +0 -48
  293. data/sig/_private/stoplight/wiring/light_factory.rbs +0 -16
  294. data/sig/_private/stoplight/wiring/notifier_factory.rbs +0 -10
  295. data/sig/_private/stoplight/wiring/system.rbs +0 -15
  296. data/sig/_private/stoplight.rbs +0 -48
  297. data/sig/stoplight/data_store.rbs +0 -19
  298. data/sig/stoplight/ports/configuration.rbs +0 -19
  299. data/sig/stoplight/ports/exception_matcher.rbs +0 -8
  300. data/sig/stoplight/ports/light.rbs +0 -12
  301. data/sig/stoplight/ports/light_info.rbs +0 -5
  302. data/sig/stoplight/ports/state_transition_notifier.rbs +0 -15
  303. /data/sig/{_private/stoplight → stoplight}/common/deprecations.rbs +0 -0
  304. /data/sig/{_private/stoplight → stoplight}/domain/compatibility_result.rbs +0 -0
  305. /data/sig/{_private/stoplight → stoplight}/domain/metrics_snapshot.rbs +0 -0
  306. /data/sig/{_private/stoplight → stoplight}/domain/ports/recovery_lock_store.rbs +0 -0
  307. /data/sig/{_private/stoplight → stoplight}/domain/ports/recovery_lock_token.rbs +0 -0
  308. /data/sig/{_private/stoplight → stoplight}/domain/ports/state_store.rbs +0 -0
  309. /data/sig/{_private/stoplight → stoplight}/domain/state_snapshot.rbs +0 -0
  310. /data/sig/{_private/stoplight → stoplight}/domain/storage/recovery_lock_token.rbs +0 -0
  311. /data/sig/{_private/stoplight → stoplight}/domain/traffic_recovery.rbs +0 -0
  312. /data/sig/{_private → stoplight}/generators/stoplight/install/install_generator.rbs +0 -0
  313. /data/sig/{_private/stoplight → stoplight}/infrastructure/fail_safe/storage/recovery_lock_token.rbs +0 -0
  314. /data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/recovery_lock.rbs +0 -0
  315. /data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/recovery_metrics.rbs +0 -0
  316. /data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/metrics.rbs +0 -0
  317. /data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/recovery_metrics.rbs +0 -0
  318. /data/sig/{_private/stoplight → stoplight}/infrastructure/system_clock.rbs +0 -0
  319. /data/sig/{_private/stoplight → stoplight}/wiring/data_store_backend.rbs +0 -0
  320. /data/sig/{_private/stoplight → stoplight}/wiring/default_config.rbs +0 -0
  321. /data/sig/{_private/stoplight → stoplight}/wiring/memory/backend.rbs +0 -0
  322. /data/sig/{_private/stoplight → stoplight}/wiring/storage_set.rbs +0 -0
  323. /data/sig/{_private/stoplight → stoplight}/wiring/storage_set_builder.rbs +0 -0
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "concurrent/map"
4
-
5
- module Stoplight
6
- module Infrastructure
7
- module Memory
8
- class DataStore
9
- # Process-local recovery lock using Ruby's Thread::Mutex.
10
- #
11
- # This only serializes recovery within a single Ruby process.
12
- # Multiple processes/servers will NOT coordinate - each process
13
- # can send probes independently.
14
- #
15
- # Mutex Lifecycle:
16
- # - One mutex created per unique light_name (lazily)
17
- # - Mutexes persist for process lifetime (never GC'd)
18
- #
19
- class RecoveryLockStore
20
- def initialize
21
- @locks = Concurrent::Map.new
22
- end
23
-
24
- # @param light_name [String]
25
- # @return [Stoplight::Infrastructure::Memory::DataStore::RecoveryLockToken, nil]
26
- def acquire_lock(light_name)
27
- lock = lock_for(light_name)
28
- RecoveryLockToken.new(light_name:) if lock.try_lock
29
- end
30
-
31
- # @param recovery_lock_token [Stoplight::Infrastructure::Memory::DataStore::RecoveryLockToken]
32
- # @return [void]
33
- def release_lock(recovery_lock_token)
34
- lock_for(recovery_lock_token.light_name).unlock
35
- end
36
-
37
- private
38
-
39
- # Stores one mutex per unique light_name for the lifetime of the process.
40
- # Mutexes are never garbage collected.
41
- attr_reader :locks
42
-
43
- private def lock_for(light_name)
44
- locks.compute_if_absent(light_name) do
45
- Thread::Mutex.new
46
- end
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Stoplight
4
- module Infrastructure
5
- module Memory
6
- class DataStore
7
- class RecoveryLockToken
8
- attr_reader :light_name
9
-
10
- def initialize(light_name:)
11
- @light_name = light_name
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Stoplight
4
- module Infrastructure
5
- module Memory
6
- class DataStore
7
- # Hash-based sliding window for O(1) amortized operations.
8
- #
9
- # Maintains a running sum and stores per-second counts in a Hash. Ruby's Hash
10
- # preserves insertion order (FIFO), allowing efficient removal of expired
11
- # buckets from the front via +Hash#shift+, with their counts subtracted from
12
- # the running sum.
13
- #
14
- # Performance: O(1) amortized for both reads and writes
15
- # Memory: Bounded to the number of buckets
16
- #
17
- # @note Not thread-safe; synchronization must be handled externally
18
- # @api private
19
- class SlidingWindow
20
- def initialize(clock:)
21
- @buckets = Hash.new { |buckets, bucket| buckets[bucket] = 0 }
22
- @running_sum = 0
23
- @clock = clock
24
- end
25
-
26
- # Increment the count at a given timestamp
27
- def increment
28
- buckets[current_bucket] += 1
29
- self.running_sum += 1
30
- end
31
-
32
- def sum_in_window(window_start)
33
- slide_window!(window_start)
34
- self.running_sum
35
- end
36
-
37
- def inspect
38
- "#<#{self.class.name} #{buckets}>"
39
- end
40
-
41
- private
42
-
43
- # A hash mapping time buckets to their counts
44
- attr_reader :buckets
45
- # The running sum of all increments in the current window
46
- attr_accessor :running_sum
47
- attr_reader :clock
48
-
49
- def slide_window!(window_start)
50
- window_start_ts = window_start.to_i
51
-
52
- loop do
53
- timestamp, sum = buckets.first
54
- if timestamp.nil? || timestamp >= window_start_ts
55
- break
56
- else
57
- self.running_sum -= sum.to_i
58
- buckets.shift
59
- end
60
- end
61
- end
62
-
63
- def current_bucket
64
- bucket_for_time(clock.current_time)
65
- end
66
-
67
- def bucket_for_time(time)
68
- time.to_i
69
- end
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Stoplight
4
- module Infrastructure
5
- module Memory
6
- class DataStore
7
- class State
8
- attr_accessor :recovered_at
9
- attr_accessor :locked_state
10
- attr_accessor :recovery_scheduled_after
11
- attr_accessor :recovery_started_at
12
- attr_accessor :breached_at
13
-
14
- def initialize
15
- @locked_state = Stoplight::State::UNLOCKED
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,342 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "monitor"
4
-
5
- module Stoplight
6
- module Infrastructure
7
- module Memory
8
- # steep:ignore:start
9
- # @see +Domain::_DataStore+
10
- class DataStore
11
- include MonitorMixin
12
-
13
- KEY_SEPARATOR = ":"
14
-
15
- # @!attribute recovery_lock_store
16
- # @return [Stoplight::Infrastructure::Memory::DataStore::RecoveryLockStore]
17
- # @api private
18
- private attr_reader :recovery_lock_store
19
-
20
- # @!attribute clock
21
- # @return [Stoplight::Domain::_Clock]
22
- private attr_reader :clock
23
-
24
- # @param recovery_lock_store [Stoplight::Infrastructure::Memory::DataStore::RecoveryLockStore]
25
- # @param clock [Stoplight::Domain::_Clock]
26
- def initialize(recovery_lock_store:, clock:)
27
- @clock = clock
28
- @recovery_lock_store = recovery_lock_store
29
- @errors = Hash.new { |errors, light_name| errors[light_name] = SlidingWindow.new(clock:) }
30
- @successes = Hash.new { |successes, light_name| successes[light_name] = SlidingWindow.new(clock:) }
31
- @metrics = Hash.new { |metrics, light_name| metrics[light_name] = Metrics.new }
32
-
33
- @recovery_metrics = Hash.new { |metrics, light_name| metrics[light_name] = Metrics.new }
34
-
35
- @states = Hash.new { |states, light_name| states[light_name] = State.new }
36
-
37
- super() # MonitorMixin
38
- end
39
-
40
- # @return [Array<String>]
41
- def names
42
- synchronize { @metrics.keys | @states.keys | @recovery_metrics.keys }
43
- end
44
-
45
- # @param config [Stoplight::Domain::Config]
46
- # @return [Stoplight::Domain::MetricsSnapshot]
47
- def get_metrics(config)
48
- light_name = config.name
49
-
50
- synchronize do
51
- current_time = clock.current_time
52
- window_start = if config.window_size
53
- (current_time - config.window_size)
54
- else
55
- current_time
56
- end
57
-
58
- metrics = @metrics[light_name]
59
-
60
- errors = @errors[light_name].sum_in_window(window_start) if config.window_size
61
- successes = @successes[light_name].sum_in_window(window_start) if config.window_size
62
- consecutive_errors = config.window_size ? [metrics.consecutive_errors, errors].min : metrics.consecutive_errors
63
- consecutive_successes = config.window_size ? [metrics.consecutive_successes.to_i, successes].min : metrics.consecutive_successes.to_i
64
-
65
- Domain::MetricsSnapshot.new(
66
- errors:,
67
- successes:,
68
- consecutive_errors:,
69
- consecutive_successes:,
70
- last_error: metrics.last_error,
71
- last_success_at: metrics.last_success_at
72
- )
73
- end
74
- end
75
-
76
- # @return [Stoplight::Domain::MetricsSnapshot]
77
- def get_recovery_metrics(config)
78
- light_name = config.name
79
-
80
- synchronize do
81
- metrics = @recovery_metrics[light_name]
82
-
83
- Domain::MetricsSnapshot.new(
84
- errors: nil, successes: nil,
85
- consecutive_errors: metrics.consecutive_errors,
86
- consecutive_successes: metrics.consecutive_successes,
87
- last_error: metrics.last_error,
88
- last_success_at: metrics.last_success_at
89
- )
90
- end
91
- end
92
-
93
- # @return [Stoplight::Domain::StateSnapshot]
94
- def get_state_snapshot(config)
95
- time, state = synchronize do
96
- [clock.current_time, @states[config.name]]
97
- end
98
-
99
- Domain::StateSnapshot.new(
100
- time:,
101
- locked_state: state.locked_state,
102
- recovery_scheduled_after: state.recovery_scheduled_after,
103
- recovery_started_at: state.recovery_started_at,
104
- breached_at: state.breached_at
105
- )
106
- end
107
-
108
- # @param config [Stoplight::Domain::Config]
109
- # @param exception [Exception]
110
- # @return [void]
111
- def record_failure(config, exception)
112
- current_time = clock.current_time
113
- light_name = config.name
114
- failure = Domain::Failure.from_error(exception, time: current_time)
115
-
116
- synchronize do
117
- @errors[light_name].increment if config.window_size
118
-
119
- metrics = @metrics[light_name]
120
-
121
- if metrics.last_error_at.nil? || failure.occurred_at > metrics.last_error_at
122
- metrics.last_error = failure
123
- end
124
-
125
- metrics.consecutive_errors += 1
126
- metrics.consecutive_successes = 0
127
- end
128
- end
129
-
130
- def clear_metrics(config)
131
- light_name = config.name
132
- synchronize do
133
- if config.window_size
134
- @errors[light_name] = SlidingWindow.new(clock:)
135
- @successes[light_name] = SlidingWindow.new(clock:)
136
- end
137
- @metrics[light_name] = Metrics.new
138
- end
139
- end
140
-
141
- def clear_recovery_metrics(config)
142
- synchronize do
143
- @recovery_metrics[config.name] = Metrics.new
144
- end
145
- end
146
-
147
- # @param config [Stoplight::Domain::Config]
148
- # @return [void]
149
- def record_success(config)
150
- light_name = config.name
151
- current_time = clock.current_time
152
-
153
- synchronize do
154
- @successes[light_name].increment if config.window_size
155
-
156
- metrics = @metrics[light_name]
157
-
158
- if metrics.last_success_at.nil? || current_time > metrics.last_success_at
159
- metrics.last_success_at = current_time
160
- end
161
-
162
- metrics.consecutive_errors = 0
163
- metrics.consecutive_successes += 1
164
- end
165
- end
166
-
167
- # @param config [Stoplight::Domain::Config]
168
- # @param exception [Exception]
169
- # @return [void]
170
- def record_recovery_probe_failure(config, exception)
171
- light_name = config.name
172
- current_time = clock.current_time
173
- failure = Domain::Failure.from_error(exception, time: current_time)
174
-
175
- synchronize do
176
- metrics = @recovery_metrics[light_name]
177
-
178
- if metrics.last_error_at.nil? || failure.occurred_at > metrics.last_error_at
179
- metrics.last_error = failure
180
- end
181
-
182
- metrics.consecutive_errors += 1
183
- metrics.consecutive_successes = 0
184
- end
185
- end
186
-
187
- # @param config [Stoplight::Domain::Config]
188
- # @return [void]
189
- def record_recovery_probe_success(config)
190
- light_name = config.name
191
- current_time = clock.current_time
192
-
193
- synchronize do
194
- metrics = @recovery_metrics[light_name]
195
- if metrics.last_success_at.nil? || current_time > metrics.last_success_at
196
- metrics.last_success_at = current_time
197
- end
198
-
199
- metrics.consecutive_errors = 0
200
- metrics.consecutive_successes += 1
201
- end
202
- end
203
-
204
- # @param config [Stoplight::Domain::Config]
205
- # @param state [String]
206
- # @return [String]
207
- def set_state(config, state)
208
- light_name = config.name
209
-
210
- synchronize do
211
- @states[light_name].locked_state = state
212
- end
213
- state
214
- end
215
-
216
- # @return [String]
217
- def inspect
218
- "#<#{self.class.name}>"
219
- end
220
-
221
- # @param config [Stoplight::Domain::Config]
222
- # @return [void]
223
- def delete_light(config)
224
- light_name = config.name
225
-
226
- synchronize do
227
- @states.delete(light_name)
228
- @recovery_metrics.delete(light_name)
229
- @metrics.delete(light_name)
230
- @errors.delete(light_name)
231
- @successes.delete(light_name)
232
- end
233
- end
234
-
235
- # Combined method that performs the state transition based on color
236
- #
237
- # @param config [Stoplight::Domain::Config] The light configuration
238
- # @param color [String] The color to transition to ("GREEN", "YELLOW", or "RED")
239
- # @return [Boolean] true if this is the first instance to detect this transition
240
- def transition_to_color(config, color)
241
- case color
242
- when Color::GREEN
243
- transition_to_green(config)
244
- when Color::YELLOW
245
- transition_to_yellow(config)
246
- when Color::RED
247
- transition_to_red(config)
248
- else
249
- raise ArgumentError, "Invalid color: #{color}"
250
- end
251
- end
252
-
253
- # @param config [Stoplight::Domain::Config]
254
- # @return [Stoplight::Infrastructure::Memory::DataStore::RecoveryLockToken, nil]
255
- def acquire_recovery_lock(config)
256
- recovery_lock_store.acquire_lock(config.name)
257
- end
258
-
259
- # @param lock [Stoplight::Infrastructure::Memory::DataStore::RecoveryLockToken]
260
- # @return [void]
261
- def release_recovery_lock(lock)
262
- recovery_lock_store.release_lock(lock)
263
- end
264
-
265
- # Transitions to GREEN state and ensures only one notification
266
- #
267
- # @param config [Stoplight::Domain::Config] The light configuration
268
- # @return [Boolean] true if this is the first instance to detect this transition
269
- private def transition_to_green(config)
270
- light_name = config.name
271
- current_time = clock.current_time
272
-
273
- synchronize do
274
- state = @states[light_name]
275
-
276
- if state.recovered_at
277
- false
278
- else
279
- state.recovered_at = current_time
280
- state.recovery_started_at = nil
281
- state.breached_at = nil
282
- state.recovery_scheduled_after = nil
283
- true
284
- end
285
- end
286
- end
287
-
288
- # Transitions to YELLOW (recovery) state and ensures only one notification
289
- #
290
- # @param config [Stoplight::Domain::Config] The light configuration
291
- # @return [Boolean] true if this is the first instance to detect this transition
292
- private def transition_to_yellow(config)
293
- light_name = config.name
294
- current_time = clock.current_time
295
-
296
- synchronize do
297
- state = @states[light_name]
298
- if state.recovery_started_at.nil?
299
- state.recovery_started_at = current_time
300
- state.recovery_scheduled_after = nil
301
- state.recovered_at = nil
302
- state.breached_at = nil
303
- true
304
- else
305
- state.recovery_scheduled_after = nil
306
- state.recovered_at = nil
307
- state.breached_at = nil
308
- false
309
- end
310
- end
311
- end
312
-
313
- # Transitions to RED state and ensures only one notification
314
- #
315
- # @param config [Stoplight::Domain::Config] The light configuration
316
- # @return [Boolean] true if this is the first instance to detect this transition
317
- private def transition_to_red(config)
318
- light_name = config.name
319
- current_time = clock.current_time
320
- recovery_scheduled_after = current_time + config.cool_off_time
321
-
322
- synchronize do
323
- state = @states[light_name]
324
- if state.breached_at
325
- state.recovery_scheduled_after = recovery_scheduled_after
326
- state.recovery_started_at = nil
327
- state.recovered_at = nil
328
- false
329
- else
330
- state.breached_at = current_time
331
- state.recovery_scheduled_after = recovery_scheduled_after
332
- state.recovery_started_at = nil
333
- state.recovered_at = nil
334
- true
335
- end
336
- end
337
- end
338
- end
339
- # steep:ignore:end
340
- end
341
- end
342
- end
@@ -1,26 +0,0 @@
1
- local number_of_metric_buckets = tonumber(ARGV[1])
2
- local window_start_ts = tonumber(ARGV[2])
3
- local window_end_ts = tonumber(ARGV[3])
4
- local metrics_keys = {}
5
- for idx = 4, #ARGV do
6
- table.insert(metrics_keys, ARGV[idx])
7
- end
8
-
9
- local metadata_key = KEYS[1]
10
-
11
- local function count_events(start_idx, bucket_count, start_ts)
12
- local total = 0
13
- for idx = start_idx, start_idx + bucket_count - 1 do
14
- total = total + tonumber(redis.call('ZCOUNT', KEYS[idx], start_ts, window_end_ts))
15
- end
16
- return total
17
- end
18
-
19
- local offset = 2
20
- local successes = count_events(2, number_of_metric_buckets, window_start_ts)
21
-
22
- offset = offset + number_of_metric_buckets
23
- local errors = count_events(offset, number_of_metric_buckets, window_start_ts)
24
-
25
- local metrics = redis.call('HMGET', metadata_key, unpack(metrics_keys))
26
- return {successes, errors, unpack(metrics)}
@@ -1,36 +0,0 @@
1
- local failure_ts = tonumber(ARGV[1])
2
- local failure_id = ARGV[2]
3
- local failure_json = ARGV[3]
4
- local bucket_ttl = tonumber(ARGV[4])
5
- local metadata_ttl = tonumber(ARGV[5])
6
-
7
- local metadata_key = KEYS[1]
8
- local errors_key = KEYS[2]
9
-
10
- -- Record failure
11
- if errors_key ~= nil then
12
- redis.call('ZADD', errors_key, failure_ts, failure_id)
13
- redis.call('EXPIRE', errors_key, bucket_ttl) -- Not supported in Redis 6.2:, 'NX')
14
- end
15
-
16
- -- Update metadata
17
- local meta = redis.call('HMGET', metadata_key, 'last_error_at', 'consecutive_errors')
18
- local prev_failure_ts = tonumber(meta[1])
19
- local prev_consecutive_errors = tonumber(meta[2])
20
-
21
- if not prev_failure_ts or failure_ts > prev_failure_ts then
22
- redis.call(
23
- 'HSET', metadata_key,
24
- 'last_error_at', failure_ts,
25
- 'last_error_json', failure_json,
26
- 'consecutive_errors', (prev_consecutive_errors or 0) + 1,
27
- 'consecutive_successes', 0
28
- )
29
- else
30
- redis.call(
31
- 'HSET', metadata_key,
32
- 'consecutive_errors', (prev_consecutive_errors or 0) + 1,
33
- 'consecutive_successes', 0
34
- )
35
- end
36
- redis.call('EXPIRE', metadata_key, metadata_ttl) -- Not supported in Redis 6.2:, 'GT')
@@ -1,27 +0,0 @@
1
- local failure_ts = tonumber(ARGV[1])
2
- local failure_json = ARGV[2]
3
-
4
- local metadata_key = KEYS[1]
5
-
6
-
7
- -- Update metadata
8
- local meta = redis.call('HMGET', metadata_key, 'last_error_at', 'consecutive_errors')
9
- local prev_failure_ts = tonumber(meta[1])
10
- local prev_consecutive_errors = tonumber(meta[2])
11
-
12
- if not prev_failure_ts or failure_ts > prev_failure_ts then
13
- redis.call(
14
- 'HSET', metadata_key,
15
- 'last_error_at', failure_ts,
16
- 'last_error_json', failure_json,
17
- 'consecutive_errors', (prev_consecutive_errors or 0) + 1,
18
- 'consecutive_successes', 0
19
- )
20
- else
21
- redis.call(
22
- 'HSET', metadata_key,
23
- 'consecutive_errors', (prev_consecutive_errors or 0) + 1,
24
- 'consecutive_successes', 0
25
- )
26
- end
27
-
@@ -1,23 +0,0 @@
1
- local request_ts = tonumber(ARGV[1])
2
-
3
- local metadata_key = KEYS[1]
4
-
5
- -- Update metadata
6
- local meta = redis.call('HMGET', metadata_key, 'last_success_at', 'consecutive_successes')
7
- local prev_success_ts = tonumber(meta[1])
8
- local prev_consecutive_successes = tonumber(meta[2])
9
-
10
- if not prev_success_ts or request_ts > prev_success_ts then
11
- redis.call(
12
- 'HSET', metadata_key,
13
- 'last_success_at', request_ts,
14
- 'consecutive_errors', 0,
15
- 'consecutive_successes', (prev_consecutive_successes or 0) + 1
16
- )
17
- else
18
- redis.call(
19
- 'HSET', metadata_key,
20
- 'consecutive_errors', 0,
21
- 'consecutive_successes', (prev_consecutive_successes or 0) + 1
22
- )
23
- end
@@ -1,35 +0,0 @@
1
- local request_ts = tonumber(ARGV[1])
2
- local request_id = ARGV[2]
3
- local bucket_ttl = tonumber(ARGV[3])
4
- local metadata_ttl = tonumber(ARGV[4])
5
-
6
- local metadata_key = KEYS[1]
7
- local successes_key = KEYS[2]
8
-
9
- -- Record success
10
- if successes_key ~= nil then
11
- redis.call('ZADD', successes_key, request_ts, request_id)
12
- redis.call('EXPIRE', successes_key, bucket_ttl) -- Not supported in Redis 6.2:, 'NX')
13
- end
14
-
15
- -- Update metadata
16
- local meta = redis.call('HMGET', metadata_key, 'last_success_at', 'consecutive_successes')
17
- local prev_success_ts = tonumber(meta[1])
18
- local prev_consecutive_successes = tonumber(meta[2])
19
-
20
- if not prev_success_ts or request_ts > prev_success_ts then
21
- redis.call(
22
- 'HSET', metadata_key,
23
- 'last_success_at', request_ts,
24
- 'consecutive_errors', 0,
25
- 'consecutive_successes', (prev_consecutive_successes or 0) + 1
26
- )
27
- else
28
- redis.call(
29
- 'HSET', metadata_key,
30
- 'consecutive_errors', 0,
31
- 'consecutive_successes', (prev_consecutive_successes or 0) + 1
32
- )
33
- end
34
-
35
- redis.call('EXPIRE', metadata_key, metadata_ttl) -- Not supported in Redis 6.2:, 'GT')
@@ -1,6 +0,0 @@
1
- local token = ARGV[1]
2
- local lock_key = KEYS[1]
3
-
4
- if redis.call("get", lock_key) == token then
5
- return redis.call("del", lock_key)
6
- end
@@ -1,10 +0,0 @@
1
- local meta_key = KEYS[1]
2
- local current_ts = tonumber(ARGV[1])
3
-
4
- -- 1 if the field is a new field in the hash and the value was set
5
- local became_green = redis.call('HSETNX', meta_key, 'recovered_at', current_ts)
6
-
7
- if became_green == 1 then
8
- redis.call("HDEL", meta_key, 'recovery_started_at', 'recovery_scheduled_after', 'breached_at')
9
- end
10
- return became_green
@@ -1,10 +0,0 @@
1
- local meta_key = KEYS[1]
2
- local current_ts = tonumber(ARGV[1])
3
- local recovery_scheduled_after_ts = tonumber(ARGV[2])
4
-
5
- -- 1 if the field is a new field in the hash and the value was set
6
- local became_red = redis.call('HSETNX', meta_key, 'breached_at', current_ts)
7
-
8
- redis.call('HSET', meta_key, 'recovery_scheduled_after', recovery_scheduled_after_ts)
9
- redis.call("HDEL", meta_key, "recovery_started_at", "recovered_at")
10
- return became_red