stoplight 5.8.2 → 6.0.0.rc1
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/CHANGELOG.md +1 -1
- data/LICENSE.md +1 -0
- data/README.md +132 -79
- data/UPGRADING.md +265 -6
- data/lib/stoplight/admin/actions/action.rb +4 -12
- data/lib/stoplight/admin/actions/lock.rb +12 -9
- data/lib/stoplight/admin/actions/lock_all.rb +27 -0
- data/lib/stoplight/admin/actions/remove.rb +12 -9
- data/lib/stoplight/admin/actions/stats.rb +15 -12
- data/lib/stoplight/admin/actions/unlock.rb +10 -9
- data/lib/stoplight/admin/assets/apple-touch-icon.png +0 -0
- data/lib/stoplight/admin/assets/favicon.ico +0 -0
- data/lib/stoplight/admin/assets/flowbite.min.css +2 -0
- data/lib/stoplight/admin/assets/flowbite.min.js +1 -0
- data/lib/stoplight/admin/assets/icon.svg +7 -0
- data/lib/stoplight/admin/assets/turbo.es2017-esm.min.js +34 -0
- data/lib/stoplight/admin/config_registry.rb +40 -0
- data/lib/stoplight/admin/dependencies.rb +29 -28
- data/lib/stoplight/admin/helpers.rb +50 -17
- data/lib/stoplight/admin/light_view.rb +184 -0
- data/lib/stoplight/admin/lights_stats.rb +7 -9
- data/lib/stoplight/admin/views/_card.erb +19 -21
- data/lib/stoplight/admin/views/index.erb +9 -3
- data/lib/stoplight/admin/views/layout.erb +45 -13
- data/lib/stoplight/admin.rb +110 -21
- data/lib/stoplight/data_store.rb +18 -8
- data/lib/stoplight/domain/config.rb +4 -1
- data/lib/stoplight/domain/error_tracking_policy.rb +9 -0
- data/lib/stoplight/domain/failure.rb +4 -0
- data/lib/stoplight/domain/id.rb +13 -0
- data/lib/stoplight/domain/light.rb +35 -77
- data/lib/stoplight/domain/lock_control.rb +55 -0
- data/lib/stoplight/domain/matcher_validator.rb +24 -0
- data/lib/stoplight/domain/state_snapshot.rb +2 -6
- data/lib/stoplight/domain/strategies/green_run_strategy.rb +33 -19
- data/lib/stoplight/domain/strategies/red_run_strategy.rb +8 -2
- data/lib/stoplight/domain/strategies/yellow_run_strategy.rb +56 -32
- data/lib/stoplight/domain/telemetry/bus.rb +90 -0
- data/lib/stoplight/domain/telemetry/consumer.rb +18 -0
- data/lib/stoplight/domain/telemetry/emitter.rb +45 -0
- data/lib/stoplight/domain/telemetry/envelope.rb +15 -0
- data/lib/stoplight/domain/telemetry/failure.rb +13 -0
- data/lib/stoplight/domain/telemetry/light_registered.rb +12 -0
- data/lib/stoplight/domain/telemetry/lock_changed.rb +19 -0
- data/lib/stoplight/domain/telemetry/metrics.rb +15 -0
- data/lib/stoplight/domain/telemetry/recovery_failed.rb +20 -0
- data/lib/stoplight/domain/telemetry/recovery_probe_completed.rb +15 -0
- data/lib/stoplight/domain/telemetry/recovery_started.rb +18 -0
- data/lib/stoplight/domain/telemetry/recovery_succeeded.rb +19 -0
- data/lib/stoplight/domain/telemetry/run_completed.rb +17 -0
- data/lib/stoplight/domain/telemetry/run_recorder.rb +58 -0
- data/lib/stoplight/domain/telemetry/settings.rb +21 -0
- data/lib/stoplight/domain/telemetry/state_transitioned.rb +11 -0
- data/lib/stoplight/domain/telemetry/subscription.rb +11 -0
- data/lib/stoplight/domain/telemetry/traffic_breached.rb +20 -0
- data/lib/stoplight/domain/tracker/recovery_probe.rb +61 -17
- data/lib/stoplight/domain/tracker/request.rb +17 -8
- data/lib/stoplight/domain/traffic_control/consecutive_errors.rb +13 -3
- data/lib/stoplight/domain/traffic_control/error_rate.rb +16 -12
- data/lib/stoplight/domain/traffic_recovery/consecutive_successes.rb +9 -3
- data/lib/stoplight/error.rb +10 -1
- data/lib/stoplight/infrastructure/config_serializer.rb +50 -0
- data/lib/stoplight/infrastructure/fail_safe/error_notifier.rb +25 -0
- data/lib/stoplight/infrastructure/fail_safe/storage/registry.rb +68 -0
- data/lib/stoplight/infrastructure/memory/storage/registry.rb +18 -0
- data/lib/stoplight/infrastructure/memory/storage/unbounded_metrics.rb +29 -32
- data/lib/stoplight/infrastructure/memory/storage/window_metrics/sliding_window.rb +74 -0
- data/lib/stoplight/infrastructure/memory/storage/window_metrics.rb +25 -24
- data/lib/stoplight/infrastructure/notifier/fail_safe.rb +3 -8
- data/lib/stoplight/infrastructure/notifier/generic.rb +3 -3
- data/lib/stoplight/infrastructure/redis/key.rb +25 -0
- data/lib/stoplight/infrastructure/redis/storage/now.lua +9 -0
- data/lib/stoplight/infrastructure/redis/storage/recovery_lock.rb +2 -4
- data/lib/stoplight/infrastructure/redis/storage/recovery_metrics.rb +1 -1
- data/lib/stoplight/infrastructure/redis/storage/registry.rb +73 -0
- data/lib/stoplight/infrastructure/redis/storage/scripting.rb +54 -3
- data/lib/stoplight/infrastructure/redis/storage/state/transition_to_green.lua +3 -1
- data/lib/stoplight/infrastructure/redis/storage/state/transition_to_red.lua +4 -2
- data/lib/stoplight/infrastructure/redis/storage/state/transition_to_yellow.lua +3 -1
- data/lib/stoplight/infrastructure/redis/storage/state.rb +8 -8
- data/lib/stoplight/infrastructure/redis/storage/unbounded_metrics/record_failure.lua +20 -21
- data/lib/stoplight/infrastructure/redis/storage/unbounded_metrics/record_success.lua +11 -19
- data/lib/stoplight/infrastructure/redis/storage/unbounded_metrics.rb +20 -16
- data/lib/stoplight/infrastructure/redis/storage/window_metrics/_evict.lua +44 -0
- data/lib/stoplight/infrastructure/redis/storage/window_metrics/metrics_snapshot.lua +14 -21
- data/lib/stoplight/infrastructure/redis/storage/window_metrics/record_failure.lua +38 -36
- data/lib/stoplight/infrastructure/redis/storage/window_metrics/record_success.lua +23 -30
- data/lib/stoplight/infrastructure/redis/storage/window_metrics.rb +45 -135
- data/lib/stoplight/infrastructure/system_clock.rb +4 -0
- data/lib/stoplight/telemetry.rb +19 -0
- data/lib/stoplight/types.rb +15 -2
- data/lib/stoplight/version.rb +1 -1
- data/lib/stoplight/wiring/config_compatibility_validator.rb +25 -2
- data/lib/stoplight/wiring/default.rb +1 -1
- data/lib/stoplight/wiring/default_config.rb +2 -1
- data/lib/stoplight/wiring/default_configuration.rb +3 -2
- data/lib/stoplight/wiring/external_caller.rb +27 -0
- data/lib/stoplight/wiring/fail_safe_config.rb +11 -0
- data/lib/stoplight/wiring/global_state.rb +93 -0
- data/lib/stoplight/wiring/{light_factory → light_configuration_dsl}/traffic_control_dsl.rb +3 -5
- data/lib/stoplight/wiring/{light_factory → light_configuration_dsl}/traffic_recovery_dsl.rb +2 -2
- data/lib/stoplight/wiring/light_configuration_dsl.rb +97 -0
- data/lib/stoplight/wiring/light_factory.rb +154 -97
- data/lib/stoplight/wiring/notifier_bridge.rb +33 -0
- data/lib/stoplight/wiring/redis/backend.rb +1 -1
- data/lib/stoplight/wiring/system/storage.rb +69 -0
- data/lib/stoplight/wiring/system.rb +125 -56
- data/lib/stoplight/wiring/{configuration_dsl.rb → system_configuration_dsl.rb} +13 -43
- data/lib/stoplight.rb +50 -194
- data/sig/sinatra/base.rbs +6 -0
- data/sig/stdlib/securerandom.rbs +4 -0
- data/sig/stoplight/admin/actions/action.rbs +10 -0
- data/sig/stoplight/admin/actions/lock.rbs +17 -0
- data/sig/stoplight/admin/actions/lock_all.rbs +17 -0
- data/sig/stoplight/admin/actions/remove.rbs +22 -0
- data/sig/stoplight/admin/actions/stats.rbs +28 -0
- data/sig/stoplight/admin/actions/unlock.rbs +17 -0
- data/sig/stoplight/admin/config_registry.rbs +20 -0
- data/sig/stoplight/admin/dependencies.rbs +16 -0
- data/sig/stoplight/admin/helpers.rbs +17 -0
- data/sig/stoplight/admin/light_view.rbs +39 -0
- data/sig/stoplight/admin/lights_stats.rbs +30 -0
- data/sig/stoplight/admin.rbs +14 -0
- data/sig/stoplight/color.rbs +3 -3
- data/sig/{_private/stoplight/data_store.rbs → stoplight/data_store/base.rbs} +1 -0
- data/sig/stoplight/data_store/memory.rbs +9 -0
- data/sig/stoplight/data_store/redis.rbs +17 -0
- data/sig/{_private/stoplight → stoplight}/domain/config.rbs +28 -24
- data/sig/{_private/stoplight → stoplight}/domain/error_tracking_policy.rbs +4 -0
- data/sig/{_private/stoplight → stoplight}/domain/failure.rbs +2 -0
- data/sig/stoplight/domain/id.rbs +7 -0
- data/sig/stoplight/domain/light.rbs +39 -0
- data/sig/{_private/stoplight → stoplight}/domain/light_info.rbs +1 -5
- data/sig/stoplight/domain/lock_control.rbs +16 -0
- data/sig/stoplight/domain/matcher_validator.rbs +11 -0
- data/sig/{_private/stoplight → stoplight}/domain/ports/clock.rbs +6 -0
- data/sig/stoplight/domain/ports/data_store.rbs +9 -0
- data/sig/stoplight/domain/ports/error_notifier.rbs +12 -0
- data/sig/stoplight/domain/ports/exception_matcher.rbs +10 -0
- data/sig/{_private/stoplight → stoplight}/domain/ports/metrics_store.rbs +2 -2
- data/sig/stoplight/domain/ports/registry.rbs +13 -0
- data/sig/{_private/stoplight → stoplight}/domain/ports/run_strategy.rbs +2 -1
- data/sig/stoplight/domain/ports/state_transition_notifier.rbs +18 -0
- data/sig/stoplight/domain/ports/telemetry.rbs +28 -0
- data/sig/stoplight/domain/ports/telemetry_publisher.rbs +14 -0
- data/sig/{_private/stoplight → stoplight}/domain/ports/traffic_control.rbs +7 -0
- data/sig/{_private/stoplight → stoplight}/domain/ports/traffic_recovery.rbs +2 -3
- data/sig/stoplight/domain/strategies/green_run_strategy.rbs +22 -0
- data/sig/stoplight/domain/strategies/red_run_strategy.rbs +19 -0
- data/sig/{_private/stoplight → stoplight}/domain/strategies/yellow_run_strategy.rbs +23 -12
- data/sig/stoplight/domain/telemetry/bus.rbs +49 -0
- data/sig/stoplight/domain/telemetry/consumer.rbs +13 -0
- data/sig/stoplight/domain/telemetry/emitter.rbs +51 -0
- data/sig/stoplight/domain/telemetry/envelope.rbs +30 -0
- data/sig/stoplight/domain/telemetry/failure.rbs +23 -0
- data/sig/stoplight/domain/telemetry/light_registered.rbs +23 -0
- data/sig/stoplight/domain/telemetry/lock_changed.rbs +31 -0
- data/sig/stoplight/domain/telemetry/metrics.rbs +27 -0
- data/sig/stoplight/domain/telemetry/recovery_failed.rbs +36 -0
- data/sig/stoplight/domain/telemetry/recovery_probe_completed.rbs +29 -0
- data/sig/stoplight/domain/telemetry/recovery_started.rbs +26 -0
- data/sig/stoplight/domain/telemetry/recovery_succeeded.rbs +31 -0
- data/sig/stoplight/domain/telemetry/run_completed.rbs +38 -0
- data/sig/stoplight/domain/telemetry/run_recorder.rbs +27 -0
- data/sig/stoplight/domain/telemetry/settings.rbs +47 -0
- data/sig/stoplight/domain/telemetry/state_transitioned.rbs +11 -0
- data/sig/stoplight/domain/telemetry/subscription.rbs +9 -0
- data/sig/stoplight/domain/telemetry/traffic_breached.rbs +36 -0
- data/sig/stoplight/domain/telemetry/types.rbs +32 -0
- data/sig/{_private/stoplight → stoplight}/domain/tracker/recovery_probe.rbs +10 -6
- data/sig/{_private/stoplight → stoplight}/domain/tracker/request.rbs +3 -3
- data/sig/{_private/stoplight → stoplight}/domain/traffic_control/consecutive_errors.rbs +2 -0
- data/sig/{_private/stoplight → stoplight}/domain/traffic_control/error_rate.rbs +3 -2
- data/sig/{_private/stoplight → stoplight}/domain/traffic_recovery/consecutive_successes.rbs +2 -0
- data/sig/stoplight/domain/types.rbs +25 -0
- data/sig/stoplight/error.rbs +8 -0
- data/sig/stoplight/generators/rails_generators_base.rbs +11 -0
- data/sig/stoplight/infrastructure/config_serializer.rbs +12 -0
- data/sig/stoplight/infrastructure/fail_safe/error_notifier.rbs +13 -0
- data/sig/{_private/stoplight → stoplight}/infrastructure/fail_safe/storage/metrics.rbs +2 -2
- data/sig/{_private/stoplight → stoplight}/infrastructure/fail_safe/storage/recovery_lock.rbs +2 -2
- data/sig/stoplight/infrastructure/fail_safe/storage/registry.rbs +23 -0
- data/sig/{_private/stoplight → stoplight}/infrastructure/fail_safe/storage/state.rbs +4 -4
- data/sig/stoplight/infrastructure/memory/storage/registry.rbs +13 -0
- data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/state.rbs +3 -3
- data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/unbounded_metrics.rbs +7 -7
- data/sig/stoplight/infrastructure/memory/storage/window_metrics/sliding_window.rbs +27 -0
- data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/window_metrics.rbs +7 -7
- data/sig/stoplight/infrastructure/notifier/fail_safe.rbs +15 -0
- data/sig/{_private/stoplight → stoplight}/infrastructure/notifier/generic.rbs +1 -1
- data/sig/{_private/stoplight → stoplight}/infrastructure/notifier/io.rbs +1 -1
- data/sig/{_private/stoplight → stoplight}/infrastructure/notifier/logger.rbs +1 -1
- data/sig/stoplight/infrastructure/redis/key.rbs +10 -0
- data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/recovery_lock.rbs +2 -2
- data/sig/stoplight/infrastructure/redis/storage/registry.rbs +27 -0
- data/sig/stoplight/infrastructure/redis/storage/scripting.rbs +34 -0
- data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/state.rbs +4 -4
- data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/unbounded_metrics.rbs +8 -1
- data/sig/stoplight/infrastructure/redis/storage/window_metrics.rbs +35 -0
- data/sig/stoplight/infrastructure/types.rbs +6 -0
- data/sig/stoplight/notifier.rbs +1 -1
- data/sig/stoplight/ports/system.rbs +16 -10
- data/sig/stoplight/state.rbs +3 -3
- data/sig/stoplight/telemetry.rbs +17 -0
- data/sig/stoplight/types.rbs +9 -0
- data/sig/{_private/stoplight → stoplight}/wiring/config_compatibility_validator.rbs +2 -0
- data/sig/stoplight/wiring/default.rbs +26 -0
- data/sig/stoplight/wiring/default_configuration.rbs +39 -0
- data/sig/stoplight/wiring/external_caller.rbs +13 -0
- data/sig/stoplight/wiring/fail_safe_config.rbs +7 -0
- data/sig/stoplight/wiring/global_state.rbs +36 -0
- data/sig/{_private/stoplight/wiring/light_factory → stoplight/wiring/light_configuration_dsl}/traffic_control_dsl.rbs +1 -1
- data/sig/{_private/stoplight/wiring/light_factory → stoplight/wiring/light_configuration_dsl}/traffic_recovery_dsl.rbs +1 -1
- data/sig/stoplight/wiring/light_configuration_dsl.rbs +38 -0
- data/sig/stoplight/wiring/light_factory.rbs +78 -0
- data/sig/stoplight/wiring/notifier_bridge.rbs +15 -0
- data/sig/stoplight/wiring/notifier_factory.rbs +10 -0
- data/sig/{_private/stoplight → stoplight}/wiring/redis/backend.rbs +6 -6
- data/sig/stoplight/wiring/system/storage.rbs +35 -0
- data/sig/stoplight/wiring/system.rbs +30 -0
- data/sig/stoplight/wiring/system_configuration_dsl.rbs +39 -0
- data/sig/stoplight/wiring/types.rbs +6 -0
- data/sig/stoplight.rbs +37 -54
- metadata +190 -143
- data/lib/stoplight/admin/actions/lock_all_green.rb +0 -18
- data/lib/stoplight/admin/actions/lock_green.rb +0 -23
- data/lib/stoplight/admin/actions/lock_red.rb +0 -23
- data/lib/stoplight/admin/lights_repository/light.rb +0 -171
- data/lib/stoplight/admin/lights_repository.rb +0 -87
- data/lib/stoplight/domain/light/configuration_builder_interface.rb +0 -236
- data/lib/stoplight/infrastructure/fail_safe/data_store.rb +0 -152
- data/lib/stoplight/infrastructure/memory/data_store/metrics.rb +0 -27
- data/lib/stoplight/infrastructure/memory/data_store/recovery_lock_store.rb +0 -52
- data/lib/stoplight/infrastructure/memory/data_store/recovery_lock_token.rb +0 -17
- data/lib/stoplight/infrastructure/memory/data_store/sliding_window.rb +0 -74
- data/lib/stoplight/infrastructure/memory/data_store/state.rb +0 -21
- data/lib/stoplight/infrastructure/memory/data_store.rb +0 -342
- data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/get_metrics.lua +0 -26
- data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_failure.lua +0 -36
- data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_recovery_probe_failure.lua +0 -27
- data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_recovery_probe_success.lua +0 -23
- data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_success.lua +0 -35
- data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/release_lock.lua +0 -6
- data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/transition_to_green.lua +0 -10
- data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/transition_to_red.lua +0 -10
- data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/transition_to_yellow.lua +0 -9
- data/lib/stoplight/infrastructure/redis/data_store/recovery_lock_store.rb +0 -60
- data/lib/stoplight/infrastructure/redis/data_store/recovery_lock_token.rb +0 -28
- data/lib/stoplight/infrastructure/redis/data_store/scripting.rb +0 -73
- data/lib/stoplight/infrastructure/redis/data_store.rb +0 -516
- data/lib/stoplight/infrastructure/redis/storage/key_space.rb +0 -51
- data/lib/stoplight/infrastructure/storage/compatibility_metrics.rb +0 -41
- data/lib/stoplight/infrastructure/storage/compatibility_recovery_lock.rb +0 -33
- data/lib/stoplight/infrastructure/storage/compatibility_recovery_metrics.rb +0 -47
- data/lib/stoplight/infrastructure/storage/compatibility_state.rb +0 -44
- data/lib/stoplight/wiring/light_builder.rb +0 -198
- data/lib/stoplight/wiring/notifier_factory.rb +0 -26
- data/lib/stoplight/wiring/system/light_builder.rb +0 -47
- data/lib/stoplight/wiring/system/light_factory.rb +0 -64
- data/sig/_private/stoplight/domain/light.rbs +0 -25
- data/sig/_private/stoplight/domain/ports/data_store.rbs +0 -76
- data/sig/_private/stoplight/domain/ports/light_factory.rbs +0 -80
- data/sig/_private/stoplight/domain/strategies/green_run_strategy.rbs +0 -17
- data/sig/_private/stoplight/domain/strategies/red_run_strategy.rbs +0 -17
- data/sig/_private/stoplight/domain/tracker/base.rbs +0 -8
- data/sig/_private/stoplight/infrastructure/fail_safe/data_store.rbs +0 -26
- data/sig/_private/stoplight/infrastructure/memory/data_store/metrics.rbs +0 -25
- data/sig/_private/stoplight/infrastructure/memory/data_store/recovery_lock_store.rbs +0 -19
- data/sig/_private/stoplight/infrastructure/memory/data_store/recovery_lock_token.rbs +0 -17
- data/sig/_private/stoplight/infrastructure/memory/data_store/sliding_window.rbs +0 -27
- data/sig/_private/stoplight/infrastructure/memory/data_store/state.rbs +0 -17
- data/sig/_private/stoplight/infrastructure/memory/data_store.rbs +0 -30
- data/sig/_private/stoplight/infrastructure/notifier/fail_safe.rbs +0 -17
- data/sig/_private/stoplight/infrastructure/redis/data_store/recovery_lock_store.rbs +0 -24
- data/sig/_private/stoplight/infrastructure/redis/data_store/recovery_lock_token.rbs +0 -21
- data/sig/_private/stoplight/infrastructure/redis/data_store/scripting.rbs +0 -34
- data/sig/_private/stoplight/infrastructure/redis/data_store.rbs +0 -67
- data/sig/_private/stoplight/infrastructure/redis/storage/key_space.rbs +0 -19
- data/sig/_private/stoplight/infrastructure/redis/storage/scripting.rbs +0 -13
- data/sig/_private/stoplight/infrastructure/redis/storage/window_metrics.rbs +0 -34
- data/sig/_private/stoplight/infrastructure/storage/compatibility_metrics.rbs +0 -17
- data/sig/_private/stoplight/infrastructure/storage/compatibility_recovery_lock.rbs +0 -13
- data/sig/_private/stoplight/infrastructure/storage/compatibility_recovery_metrics.rbs +0 -14
- data/sig/_private/stoplight/infrastructure/storage/compatibility_state.rbs +0 -14
- data/sig/_private/stoplight/system/light_builder.rbs +0 -23
- data/sig/_private/stoplight/system/light_factory.rbs +0 -17
- data/sig/_private/stoplight/types.rbs +0 -6
- data/sig/_private/stoplight/wiring/configuration_dsl.rbs +0 -43
- data/sig/_private/stoplight/wiring/default.rbs +0 -26
- data/sig/_private/stoplight/wiring/default_configuration.rbs +0 -29
- data/sig/_private/stoplight/wiring/light_builder.rbs +0 -48
- data/sig/_private/stoplight/wiring/light_factory.rbs +0 -16
- data/sig/_private/stoplight/wiring/notifier_factory.rbs +0 -10
- data/sig/_private/stoplight/wiring/system.rbs +0 -15
- data/sig/_private/stoplight.rbs +0 -48
- data/sig/stoplight/data_store.rbs +0 -19
- data/sig/stoplight/ports/configuration.rbs +0 -19
- data/sig/stoplight/ports/exception_matcher.rbs +0 -8
- data/sig/stoplight/ports/light.rbs +0 -12
- data/sig/stoplight/ports/light_info.rbs +0 -5
- data/sig/stoplight/ports/state_transition_notifier.rbs +0 -15
- /data/sig/{_private/stoplight → stoplight}/common/deprecations.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/domain/compatibility_result.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/domain/metrics_snapshot.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/domain/ports/recovery_lock_store.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/domain/ports/recovery_lock_token.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/domain/ports/state_store.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/domain/state_snapshot.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/domain/storage/recovery_lock_token.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/domain/traffic_recovery.rbs +0 -0
- /data/sig/{_private → stoplight}/generators/stoplight/install/install_generator.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/infrastructure/fail_safe/storage/recovery_lock_token.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/recovery_lock.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/infrastructure/memory/storage/recovery_metrics.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/metrics.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/infrastructure/redis/storage/recovery_metrics.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/infrastructure/system_clock.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/wiring/data_store_backend.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/wiring/default_config.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/wiring/memory/backend.rbs +0 -0
- /data/sig/{_private/stoplight → stoplight}/wiring/storage_set.rbs +0 -0
- /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')
|
data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_recovery_probe_failure.lua
DELETED
|
@@ -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
|
-
|
data/lib/stoplight/infrastructure/redis/data_store/lua_scripts/record_recovery_probe_success.lua
DELETED
|
@@ -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,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
|