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.
- 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,51 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "digest"
|
|
4
|
-
|
|
5
|
-
module Stoplight
|
|
6
|
-
module Infrastructure
|
|
7
|
-
module Redis
|
|
8
|
-
module Storage
|
|
9
|
-
# Immutable key namespace for a light within a system.
|
|
10
|
-
#
|
|
11
|
-
# Produces keys following entity-first structure:
|
|
12
|
-
# stoplight:v6:{system_id}:{light_id}:locks:recovery
|
|
13
|
-
# stoplight:v6:{system_id}:{light_id}:metrics:successes
|
|
14
|
-
# stoplight:v6:{system_id}:{light_id}:state
|
|
15
|
-
#
|
|
16
|
-
# Identifiers are derived from SHA-256 and truncated to 12 characters. Collisions are extremely
|
|
17
|
-
# unlikely at expected system scale.
|
|
18
|
-
#
|
|
19
|
-
# @example
|
|
20
|
-
# key_space = KeySpace.build(system_name: "payments", light_name: "stripe-api")
|
|
21
|
-
# key_space.key(:locks, :recovery) #=> "stoplight:v6:df384ae97c77:cfe6861fa39e:locks:recovery"
|
|
22
|
-
#
|
|
23
|
-
KeySpace = Data.define(:system_id, :light_id)
|
|
24
|
-
|
|
25
|
-
class KeySpace
|
|
26
|
-
# @!attribute system_id
|
|
27
|
-
# 12-char hex identifier for the system
|
|
28
|
-
#
|
|
29
|
-
# @!attribute light_id
|
|
30
|
-
# 12-char hex identifier for the light
|
|
31
|
-
|
|
32
|
-
class << self
|
|
33
|
-
def build(system_name:, light_name:) = new(
|
|
34
|
-
system_id: hash_name(system_name),
|
|
35
|
-
light_id: hash_name(light_name)
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
# Generates a truncated SHA256 hash for use in Redis keys.
|
|
39
|
-
def hash_name(name) = Digest::SHA256.hexdigest(name.to_s)[0, 12] #: String
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Builds a Redis key within this namespace.
|
|
43
|
-
#
|
|
44
|
-
# @param pieces Key segments to append
|
|
45
|
-
# @return Full Redis key
|
|
46
|
-
def key(*pieces) = [:stoplight, :v5, system_id, "{#{light_id}}", *pieces].join(":")
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module Infrastructure
|
|
5
|
-
module Storage
|
|
6
|
-
# Temporary adapter that bridges Domain::Storage::Metrics to existing DataStore.
|
|
7
|
-
#
|
|
8
|
-
# This compatibility layer allows the metrics abstraction to be introduced
|
|
9
|
-
# without breaking existing data store implementations. It delegates all
|
|
10
|
-
# operations to the data store's original methods.
|
|
11
|
-
#
|
|
12
|
-
# This class will be removed in a future versions once all data stores
|
|
13
|
-
# have native metrics implementations.
|
|
14
|
-
#
|
|
15
|
-
# @example Creating metrics for a circuit
|
|
16
|
-
# metrics = CompatibilityMetrics.new(
|
|
17
|
-
# data_store: redis_store,
|
|
18
|
-
# config: config
|
|
19
|
-
# )
|
|
20
|
-
# metrics.record_success
|
|
21
|
-
#
|
|
22
|
-
class CompatibilityMetrics
|
|
23
|
-
attr_reader :data_store
|
|
24
|
-
attr_reader :config
|
|
25
|
-
|
|
26
|
-
def initialize(data_store:, config:)
|
|
27
|
-
@data_store = data_store
|
|
28
|
-
@config = config
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def metrics_snapshot = data_store.get_metrics(config)
|
|
32
|
-
|
|
33
|
-
def record_success = data_store.record_success(config)
|
|
34
|
-
|
|
35
|
-
def record_failure(error) = data_store.record_failure(config, error)
|
|
36
|
-
|
|
37
|
-
def clear = data_store.clear_metrics(config)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module Infrastructure
|
|
5
|
-
module Storage
|
|
6
|
-
# Temporary adapter that bridges +Domain::Storage::RecoveryLock+ to existing DataStore.
|
|
7
|
-
#
|
|
8
|
-
# This compatibility layer allows the recovery lock abstraction to be
|
|
9
|
-
# introduced without breaking existing data store implementations. It
|
|
10
|
-
# delegates all lock operations to the data store's original methods.
|
|
11
|
-
#
|
|
12
|
-
# This adapter will be removed in a future versions once all
|
|
13
|
-
# data stores have native recovery lock implementations.
|
|
14
|
-
#
|
|
15
|
-
# @see Stoplight::Domain::_RecoveryLockStore
|
|
16
|
-
class CompatibilityRecoveryLock
|
|
17
|
-
def initialize(data_store:, config:)
|
|
18
|
-
@data_store = data_store
|
|
19
|
-
@config = config
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def acquire_lock = data_store.acquire_recovery_lock(config) #: Domain::Storage::RecoveryLockToken?
|
|
23
|
-
|
|
24
|
-
def release_lock(lock) = data_store.release_recovery_lock(lock)
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
attr_reader :data_store
|
|
29
|
-
attr_reader :config
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module Infrastructure
|
|
5
|
-
module Storage
|
|
6
|
-
# When a circuit is RED (open), Stoplight periodically sends "recovery probes"
|
|
7
|
-
# to test whether the protected service has recovered. These test requests have
|
|
8
|
-
# different semantics than normal requests and their metrics are tracked separately.
|
|
9
|
-
#
|
|
10
|
-
# Like +CompatibilityMetrics+, this adapter will be replaced with purpose-built
|
|
11
|
-
# recovery metrics implementations (e.g., +ConsecutiveSuccessMetrics+) once the
|
|
12
|
-
# metrics extraction is complete.
|
|
13
|
-
#
|
|
14
|
-
# @example Recovery probe flow
|
|
15
|
-
# # Circuit is RED, start probing
|
|
16
|
-
# recovery_metrics = CompatibilityRecoveryMetrics.new(
|
|
17
|
-
# data_store: redis_store,
|
|
18
|
-
# config: circuit_config
|
|
19
|
-
# )
|
|
20
|
-
#
|
|
21
|
-
# recovery_metrics.record_success
|
|
22
|
-
# recovery_metrics.metrics_snapshot # => 1 success, 0 failures
|
|
23
|
-
#
|
|
24
|
-
class CompatibilityRecoveryMetrics
|
|
25
|
-
def initialize(data_store:, config:)
|
|
26
|
-
@data_store = data_store
|
|
27
|
-
@config = config
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def metrics_snapshot = data_store.get_recovery_metrics(config)
|
|
31
|
-
|
|
32
|
-
# Tracks successful circuit breaker execution
|
|
33
|
-
def record_success = data_store.record_recovery_probe_success(config)
|
|
34
|
-
|
|
35
|
-
# Tracks failed circuit breaker execution
|
|
36
|
-
def record_failure(error) = data_store.record_recovery_probe_failure(config, error)
|
|
37
|
-
|
|
38
|
-
def clear = data_store.clear_recovery_metrics(config)
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
|
|
42
|
-
attr_reader :data_store
|
|
43
|
-
attr_reader :config
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module Infrastructure
|
|
5
|
-
module Storage
|
|
6
|
-
# Temporary adapter that bridges Domain::Storage::State to existing DataStore.
|
|
7
|
-
#
|
|
8
|
-
# This compatibility layer allows the state abstraction to be introduced
|
|
9
|
-
# without breaking existing data store implementations. It delegates all
|
|
10
|
-
# state operations to the data store's original methods.
|
|
11
|
-
#
|
|
12
|
-
# This adapter will be removed in a future versions once all
|
|
13
|
-
# data stores have native state storage implementations.
|
|
14
|
-
#
|
|
15
|
-
# @example Creating state storage for a circuit
|
|
16
|
-
# state = CompatibilityState.new(
|
|
17
|
-
# data_store: redis_store,
|
|
18
|
-
# config: circuit_config
|
|
19
|
-
# )
|
|
20
|
-
# state.set_state(State::LOCKED_RED)
|
|
21
|
-
# snapshot = state.state_snapshot
|
|
22
|
-
#
|
|
23
|
-
class CompatibilityState
|
|
24
|
-
def initialize(data_store:, config:)
|
|
25
|
-
@data_store = data_store
|
|
26
|
-
@config = config
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def state_snapshot = data_store.get_state_snapshot(config)
|
|
30
|
-
|
|
31
|
-
def set_state(state) = data_store.set_state(config, state)
|
|
32
|
-
|
|
33
|
-
def transition_to_color(color) = data_store.transition_to_color(config, color)
|
|
34
|
-
|
|
35
|
-
def clear = data_store.delete_light(config)
|
|
36
|
-
|
|
37
|
-
private
|
|
38
|
-
|
|
39
|
-
attr_reader :data_store
|
|
40
|
-
attr_reader :config
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "concurrent/map"
|
|
4
|
-
|
|
5
|
-
module Stoplight
|
|
6
|
-
module Wiring
|
|
7
|
-
# Constructs a fully-wired Light instance from validated configuration.
|
|
8
|
-
#
|
|
9
|
-
# LightBuilder is the final assembly step in the Light creation pipeline.
|
|
10
|
-
# It receives validated config and dependencies from ConfigurationPipeline
|
|
11
|
-
# and wires together all infrastructure components (data stores, trackers,
|
|
12
|
-
# strategies) needed for a functioning circuit breaker.
|
|
13
|
-
#
|
|
14
|
-
# LightBuilder maintains a global registry (MEMORY_REGISTRY) that ensures
|
|
15
|
-
# the same Memory data store config object always produces the same
|
|
16
|
-
# data store instance:
|
|
17
|
-
#
|
|
18
|
-
# data_store = Stoplight::DataStore::Memory.new
|
|
19
|
-
# light1 = Stoplight("foo", data_store: data_store)
|
|
20
|
-
# light2 = Stoplight("bar", data_store: data_store)
|
|
21
|
-
# # light1 and light2 share the same underlying memory store
|
|
22
|
-
#
|
|
23
|
-
# light3 = Stoplight("baz", data_store: Stoplight::DataStore::Memory.new)
|
|
24
|
-
# # light3 has its own independent store
|
|
25
|
-
#
|
|
26
|
-
# This singleton behavior is keyed by config object identity (object_id),
|
|
27
|
-
# not by value equality.
|
|
28
|
-
#
|
|
29
|
-
# @api private
|
|
30
|
-
class LightBuilder
|
|
31
|
-
FAILOVER_DATA_STORE_CONFIG = Stoplight::DataStore::Memory.new
|
|
32
|
-
private_constant :FAILOVER_DATA_STORE_CONFIG
|
|
33
|
-
|
|
34
|
-
MEMORY_REGISTRY = Concurrent::Map.new
|
|
35
|
-
private_constant :MEMORY_REGISTRY
|
|
36
|
-
|
|
37
|
-
def initialize(config:, factory:)
|
|
38
|
-
@clock = Infrastructure::SystemClock.new
|
|
39
|
-
@config = config
|
|
40
|
-
@name = T.must(config.name)
|
|
41
|
-
@cool_off_time = config.cool_off_time
|
|
42
|
-
|
|
43
|
-
@data_store_config = config.data_store
|
|
44
|
-
@error_notifier = config.error_notifier
|
|
45
|
-
@factory = factory
|
|
46
|
-
@notifiers = config.notifiers
|
|
47
|
-
@traffic_recovery = config.traffic_recovery
|
|
48
|
-
@traffic_control = config.traffic_control
|
|
49
|
-
|
|
50
|
-
@error_tracking_policy = Domain::ErrorTrackingPolicy.new(
|
|
51
|
-
tracked: config.tracked_errors,
|
|
52
|
-
skipped: config.skipped_errors
|
|
53
|
-
)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def build
|
|
57
|
-
Stoplight::Domain::Light.new(
|
|
58
|
-
@name,
|
|
59
|
-
state_store:,
|
|
60
|
-
green_run_strategy:,
|
|
61
|
-
yellow_run_strategy:,
|
|
62
|
-
red_run_strategy:,
|
|
63
|
-
factory:
|
|
64
|
-
)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
private
|
|
68
|
-
|
|
69
|
-
attr_reader :data_store_config
|
|
70
|
-
attr_reader :error_notifier
|
|
71
|
-
attr_reader :factory
|
|
72
|
-
attr_reader :clock
|
|
73
|
-
attr_reader :traffic_control
|
|
74
|
-
attr_reader :traffic_recovery
|
|
75
|
-
attr_reader :config
|
|
76
|
-
|
|
77
|
-
def state_store = Stoplight::Infrastructure::Storage::CompatibilityState.new(config:, data_store:)
|
|
78
|
-
|
|
79
|
-
# @return [<Stoplight::Notifier::Base>]
|
|
80
|
-
def notifiers
|
|
81
|
-
Array(@notifiers).map do |notifier|
|
|
82
|
-
Infrastructure::Notifier::FailSafe.new(notifier:, error_notifier:)
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def redis_recovery_lock_store
|
|
87
|
-
Infrastructure::Redis::DataStore::RecoveryLockStore.new(
|
|
88
|
-
redis:,
|
|
89
|
-
lock_timeout: config.cool_off_time_in_milliseconds,
|
|
90
|
-
scripting:
|
|
91
|
-
)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def scripting = Infrastructure::Redis::DataStore::Scripting.new(redis:)
|
|
95
|
-
|
|
96
|
-
def memory_recovery_lock_store
|
|
97
|
-
Infrastructure::Memory::DataStore::RecoveryLockStore.new
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def failover_data_store
|
|
101
|
-
create_data_store(FAILOVER_DATA_STORE_CONFIG)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def data_store
|
|
105
|
-
create_data_store(data_store_config)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def metrics_store
|
|
109
|
-
Stoplight::Infrastructure::Storage::CompatibilityMetrics.new(config:, data_store:)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def recovery_lock_store
|
|
113
|
-
Stoplight::Infrastructure::Storage::CompatibilityRecoveryLock.new(config:, data_store:)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def request_tracker
|
|
117
|
-
Domain::Tracker::Request.new(traffic_control:, notifiers:, config:, metrics_store:, state_store:)
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def recovery_probe_tracker
|
|
121
|
-
Domain::Tracker::RecoveryProbe.new(
|
|
122
|
-
traffic_recovery:,
|
|
123
|
-
notifiers:,
|
|
124
|
-
config:,
|
|
125
|
-
metrics_store: recovery_metrics_store,
|
|
126
|
-
state_store:
|
|
127
|
-
)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def recovery_metrics_store
|
|
131
|
-
Stoplight::Infrastructure::Storage::CompatibilityRecoveryMetrics.new(config:, data_store:)
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def green_run_strategy
|
|
135
|
-
Domain::Strategies::GreenRunStrategy.new(
|
|
136
|
-
error_tracking_policy: @error_tracking_policy,
|
|
137
|
-
request_tracker:
|
|
138
|
-
)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def yellow_run_strategy
|
|
142
|
-
Domain::Strategies::YellowRunStrategy.new(
|
|
143
|
-
name: @name,
|
|
144
|
-
error_tracking_policy: @error_tracking_policy,
|
|
145
|
-
notifiers:,
|
|
146
|
-
request_tracker: recovery_probe_tracker,
|
|
147
|
-
red_run_strategy:,
|
|
148
|
-
state_store:,
|
|
149
|
-
metrics_store:,
|
|
150
|
-
recovery_lock_store:,
|
|
151
|
-
config: @config
|
|
152
|
-
)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def red_run_strategy
|
|
156
|
-
Domain::Strategies::RedRunStrategy.new(name: @name, cool_off_time: @cool_off_time)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def create_data_store(data_store_config)
|
|
160
|
-
case data_store_config
|
|
161
|
-
when Stoplight::DataStore::Memory
|
|
162
|
-
memory_registry.compute_if_absent(data_store_config.object_id) do
|
|
163
|
-
Infrastructure::Memory::DataStore.new(
|
|
164
|
-
recovery_lock_store: memory_recovery_lock_store,
|
|
165
|
-
clock:
|
|
166
|
-
)
|
|
167
|
-
end
|
|
168
|
-
when Stoplight::DataStore::Redis
|
|
169
|
-
Infrastructure::FailSafe::DataStore.new(
|
|
170
|
-
data_store: Stoplight::Infrastructure::Redis::DataStore.new(
|
|
171
|
-
clock:,
|
|
172
|
-
redis: data_store_config.redis,
|
|
173
|
-
warn_on_clock_skew: data_store_config.warn_on_clock_skew,
|
|
174
|
-
recovery_lock_store: redis_recovery_lock_store,
|
|
175
|
-
scripting:
|
|
176
|
-
),
|
|
177
|
-
error_notifier:,
|
|
178
|
-
failover_data_store:,
|
|
179
|
-
circuit_breaker: Stoplight.system_light("data_store:fail_safe:redis")
|
|
180
|
-
)
|
|
181
|
-
else
|
|
182
|
-
raise NoMatchingPatternError, data_store_config
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def redis
|
|
187
|
-
case data_store_config
|
|
188
|
-
when DataStore::Redis
|
|
189
|
-
data_store_config.redis
|
|
190
|
-
else
|
|
191
|
-
raise TypeError, "Expected Stoplight::DataStore::Redis, got #{data_store_config.class}"
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def memory_registry = MEMORY_REGISTRY
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module Wiring
|
|
5
|
-
class NotifierFactory
|
|
6
|
-
class << self
|
|
7
|
-
# Wraps a notifier with fail-safe mechanisms.
|
|
8
|
-
#
|
|
9
|
-
# @param notifier [Stoplight::Domain::StateTransitionNotifier] The notifier to wrap.
|
|
10
|
-
# @param error_notifier [Proc] called when wrapped data store fails
|
|
11
|
-
# @return [Stoplight::Notifier::FailSafe] The original notifier if it is already
|
|
12
|
-
# a +FailSafe+ instance, otherwise a new +FailSafe+ instance.
|
|
13
|
-
def create(notifier:, error_notifier:)
|
|
14
|
-
case notifier
|
|
15
|
-
in Infrastructure::Notifier::FailSafe if notifier.error_notifier == error_notifier
|
|
16
|
-
notifier
|
|
17
|
-
in Infrastructure::Notifier::FailSafe
|
|
18
|
-
Infrastructure::Notifier::FailSafe.new(notifier: notifier.notifier, error_notifier:)
|
|
19
|
-
else
|
|
20
|
-
Infrastructure::Notifier::FailSafe.new(notifier:, error_notifier:)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module Wiring
|
|
5
|
-
class System
|
|
6
|
-
class LightBuilder < Wiring::LightBuilder
|
|
7
|
-
def initialize(system:, config:, factory:)
|
|
8
|
-
@system = system
|
|
9
|
-
|
|
10
|
-
super(config:, factory:)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def key_space = @key_space ||= Infrastructure::Redis::Storage::KeySpace.build(
|
|
14
|
-
system_name: system.name,
|
|
15
|
-
light_name: config.name
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
def storage_set
|
|
19
|
-
@storage_set ||= StorageSetBuilder.new(backend: build_backend, windowed: !config.window_size.nil?).build
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
attr_reader :system
|
|
25
|
-
|
|
26
|
-
def state_store = storage_set.state_store
|
|
27
|
-
def recovery_lock_store = storage_set.recovery_lock_store
|
|
28
|
-
def recovery_metrics_store = storage_set.recovery_metrics_store
|
|
29
|
-
def metrics_store = storage_set.metrics_store
|
|
30
|
-
def storage_scripting = Infrastructure::Redis::Storage::Scripting.new(redis:)
|
|
31
|
-
def failover_system = @failover_system ||= Stoplight.__stoplight__system("failover-#{system.name}")
|
|
32
|
-
|
|
33
|
-
def build_backend
|
|
34
|
-
case data_store_config
|
|
35
|
-
in DataStore::Memory
|
|
36
|
-
Memory::Backend.new(clock:, config:)
|
|
37
|
-
in DataStore::Redis
|
|
38
|
-
Redis::Backend.new(
|
|
39
|
-
redis:, scripting: storage_scripting, key_space:, clock:, config:, error_notifier:,
|
|
40
|
-
failover_light: failover_system.light("redis")
|
|
41
|
-
)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module Wiring
|
|
5
|
-
class System
|
|
6
|
-
class LightFactory < Wiring::LightFactory
|
|
7
|
-
attr_reader :system
|
|
8
|
-
|
|
9
|
-
def initialize(system:, config:)
|
|
10
|
-
@system = system
|
|
11
|
-
|
|
12
|
-
super(config:)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def with(
|
|
16
|
-
name: T.undefined,
|
|
17
|
-
cool_off_time: T.undefined,
|
|
18
|
-
threshold: T.undefined,
|
|
19
|
-
recovery_threshold: T.undefined,
|
|
20
|
-
window_size: T.undefined,
|
|
21
|
-
tracked_errors: T.undefined,
|
|
22
|
-
skipped_errors: T.undefined,
|
|
23
|
-
data_store: T.undefined,
|
|
24
|
-
error_notifier: T.undefined,
|
|
25
|
-
notifiers: T.undefined,
|
|
26
|
-
traffic_control: T.undefined,
|
|
27
|
-
traffic_recovery: T.undefined
|
|
28
|
-
)
|
|
29
|
-
self.class.new(
|
|
30
|
-
system:,
|
|
31
|
-
config: ConfigurationDsl.new(
|
|
32
|
-
cool_off_time:,
|
|
33
|
-
threshold:,
|
|
34
|
-
recovery_threshold:,
|
|
35
|
-
window_size:,
|
|
36
|
-
tracked_errors:,
|
|
37
|
-
skipped_errors:,
|
|
38
|
-
traffic_control:,
|
|
39
|
-
traffic_recovery:,
|
|
40
|
-
error_notifier:,
|
|
41
|
-
data_store:,
|
|
42
|
-
notifiers:
|
|
43
|
-
).configure!(config)
|
|
44
|
-
)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
class InternalLightFactory < Wiring::LightFactory
|
|
48
|
-
def initialize
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def with(**untyped) # steep:ignore
|
|
52
|
-
raise NotImplementedError, "You're not allowed to extend system lights"
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
private def light_builder(config:)
|
|
57
|
-
System::LightBuilder.new(system:, factory: light_factory, config:)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
private def light_factory = InternalLightFactory.new
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module Stoplight
|
|
2
|
-
module Domain
|
|
3
|
-
class Light
|
|
4
|
-
include _Light
|
|
5
|
-
attr_reader green_run_strategy: Strategies::GreenRunStrategy
|
|
6
|
-
attr_reader yellow_run_strategy: Strategies::YellowRunStrategy
|
|
7
|
-
attr_reader red_run_strategy: Strategies::RedRunStrategy
|
|
8
|
-
attr_reader state_store: Domain::_StateStore
|
|
9
|
-
attr_reader factory: _LightFactory
|
|
10
|
-
@name: String
|
|
11
|
-
|
|
12
|
-
def initialize: (
|
|
13
|
-
String name,
|
|
14
|
-
green_run_strategy: Strategies::GreenRunStrategy,
|
|
15
|
-
yellow_run_strategy: Strategies::YellowRunStrategy,
|
|
16
|
-
red_run_strategy: Strategies::RedRunStrategy,
|
|
17
|
-
factory: _LightFactory,
|
|
18
|
-
state_store: Domain::_StateStore
|
|
19
|
-
) -> void
|
|
20
|
-
|
|
21
|
-
private def state_strategy_factory: (color) -> _RunStrategy
|
|
22
|
-
private def state_snapshot: -> StateSnapshot
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module Domain
|
|
5
|
-
interface _DataStore
|
|
6
|
-
# Retrieves the names of all lights stored in the data store.
|
|
7
|
-
#
|
|
8
|
-
# @return An array of light names.
|
|
9
|
-
def names: -> Array[String]
|
|
10
|
-
|
|
11
|
-
# Retrieves metrics for a specific light configuration.
|
|
12
|
-
def get_metrics: (Config) -> Domain::MetricsSnapshot
|
|
13
|
-
|
|
14
|
-
# Retrieves recovery metrics for a specific light configuration.
|
|
15
|
-
def get_recovery_metrics: (Config) -> Domain::MetricsSnapshot
|
|
16
|
-
|
|
17
|
-
# Retrieves State Snapshot for a specific light configuration.
|
|
18
|
-
def get_state_snapshot: (Config) -> StateSnapshot
|
|
19
|
-
|
|
20
|
-
# Clears windowed metrics (successes/errors) to prevent
|
|
21
|
-
# stale failures from before recovery from affecting post-recovery decisions.
|
|
22
|
-
# Consecutive counts are intentionally preserved as they track current streaks.
|
|
23
|
-
def clear_metrics: (Config) -> void
|
|
24
|
-
|
|
25
|
-
def clear_recovery_metrics: (Config) -> void
|
|
26
|
-
|
|
27
|
-
# Records a failure for a specific light configuration.
|
|
28
|
-
def record_failure: (Config, StandardError exception) -> void
|
|
29
|
-
|
|
30
|
-
# Records a success for a specific light configuration.
|
|
31
|
-
def record_success: (Config) -> void
|
|
32
|
-
|
|
33
|
-
# Records a failed recovery probe for a specific light configuration.
|
|
34
|
-
def record_recovery_probe_failure: (Config, StandardError exception) -> void
|
|
35
|
-
|
|
36
|
-
# Records a successful recovery probe for a specific light configuration.
|
|
37
|
-
def record_recovery_probe_success: (Config) -> void
|
|
38
|
-
|
|
39
|
-
# Sets the state of a specific light configuration.
|
|
40
|
-
def set_state: (Config, state state) -> state
|
|
41
|
-
|
|
42
|
-
# Acquires recovery lock for serializing probe execution.
|
|
43
|
-
def acquire_recovery_lock: (Config) -> _RecoveryLockToken?
|
|
44
|
-
|
|
45
|
-
# Releases previously acquired lock.
|
|
46
|
-
def release_recovery_lock: (_RecoveryLockToken lock) -> void
|
|
47
|
-
|
|
48
|
-
# Transitions the Stoplight to the specified color.
|
|
49
|
-
#
|
|
50
|
-
# This method performs a color transition operation that works across distributed instances
|
|
51
|
-
# of the light. It ensures that in a multi-instance environment, only one instance
|
|
52
|
-
# is considered the "first" to perform the transition (and therefore responsible for
|
|
53
|
-
# triggering notifications).
|
|
54
|
-
#
|
|
55
|
-
# @param config
|
|
56
|
-
# @param color The target color/state to transition to.
|
|
57
|
-
# Should be one of Stoplight::Color::GREEN, Stoplight::Color::YELLOW, or Stoplight::Color::RED.
|
|
58
|
-
#
|
|
59
|
-
# @return [Boolean] Returns +true+ if this instance was the first to perform this specific transition
|
|
60
|
-
# (and should therefore trigger notifications). Returns +false+ if another instance already
|
|
61
|
-
# initiated this transition.
|
|
62
|
-
#
|
|
63
|
-
# @note In distributed environments with multiple instances, race conditions can occur when instances
|
|
64
|
-
# attempt conflicting transitions simultaneously (e.g., one instance tries to transition from
|
|
65
|
-
# YELLOW to GREEN while another tries YELLOW to RED). The implementation handles this, but
|
|
66
|
-
# be aware that the last operation may determine the final color of the light.
|
|
67
|
-
#
|
|
68
|
-
def transition_to_color: (Config, color color) -> bool
|
|
69
|
-
|
|
70
|
-
# Deletes metadata (and related persistent state) for the given light.
|
|
71
|
-
#
|
|
72
|
-
# Implementations may choose to only remove metadata; metrics may expire via TTL.
|
|
73
|
-
def delete_light: (Config) -> void
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|