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,171 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "securerandom"
|
|
4
|
-
|
|
5
|
-
module Stoplight
|
|
6
|
-
class Admin
|
|
7
|
-
class LightsRepository
|
|
8
|
-
class Light
|
|
9
|
-
COLORS = [
|
|
10
|
-
GREEN = Stoplight::Color::GREEN,
|
|
11
|
-
YELLOW = Stoplight::Color::YELLOW,
|
|
12
|
-
RED = Stoplight::Color::RED
|
|
13
|
-
].freeze
|
|
14
|
-
|
|
15
|
-
# @!attribute id
|
|
16
|
-
# @return [String]
|
|
17
|
-
attr_reader :id
|
|
18
|
-
|
|
19
|
-
# @!attribute name
|
|
20
|
-
# @return [String]
|
|
21
|
-
attr_reader :name
|
|
22
|
-
|
|
23
|
-
# @!attribute color
|
|
24
|
-
# @return [String]
|
|
25
|
-
attr_reader :color
|
|
26
|
-
|
|
27
|
-
# @!attribute state
|
|
28
|
-
# @return [String]
|
|
29
|
-
attr_reader :state
|
|
30
|
-
|
|
31
|
-
# @!attribute failures
|
|
32
|
-
# @return [<Stoplight::Failure>]
|
|
33
|
-
attr_reader :failures
|
|
34
|
-
|
|
35
|
-
# @!attribute failure_count
|
|
36
|
-
# @return [Integer]
|
|
37
|
-
attr_reader :failure_count
|
|
38
|
-
|
|
39
|
-
# @param name [String]
|
|
40
|
-
# @param color [String]
|
|
41
|
-
# @param state [String]
|
|
42
|
-
# @param failures [<Stoplight::Failure>]
|
|
43
|
-
# @param failure_count [Integer, nil]
|
|
44
|
-
def initialize(name:, color:, state:, failures:, failure_count: nil)
|
|
45
|
-
@id = SecureRandom.uuid
|
|
46
|
-
@name = name
|
|
47
|
-
@color = color
|
|
48
|
-
@state = state
|
|
49
|
-
@failures = failures
|
|
50
|
-
@failure_count = failure_count
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def latest_failure
|
|
54
|
-
failures.first
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# @return [Boolean]
|
|
58
|
-
def locked?
|
|
59
|
-
!unlocked?
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# @return [Boolean]
|
|
63
|
-
def unlocked?
|
|
64
|
-
state == Stoplight::State::UNLOCKED
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# @return [Hash]
|
|
68
|
-
def as_json
|
|
69
|
-
{
|
|
70
|
-
name: name,
|
|
71
|
-
color: color,
|
|
72
|
-
failures: failures,
|
|
73
|
-
locked: locked?
|
|
74
|
-
}
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# @return [Array]
|
|
78
|
-
def default_sort_key
|
|
79
|
-
[-COLORS.index(color), name]
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def last_check = latest_failure&.time # TODO: take into account positive checks as well
|
|
83
|
-
|
|
84
|
-
# @return [String, nil]
|
|
85
|
-
def last_check_in_words
|
|
86
|
-
last_error_time = latest_failure&.time
|
|
87
|
-
return unless last_error_time
|
|
88
|
-
|
|
89
|
-
time_difference = Time.now.utc - last_error_time
|
|
90
|
-
if time_difference < 1
|
|
91
|
-
"just now"
|
|
92
|
-
elsif time_difference < 60
|
|
93
|
-
"#{time_difference.to_i}s ago"
|
|
94
|
-
elsif time_difference < 3600
|
|
95
|
-
"#{(time_difference / 60).to_i}m ago"
|
|
96
|
-
elsif time_difference < 86400
|
|
97
|
-
"#{(time_difference / 3600).to_i}h ago"
|
|
98
|
-
else
|
|
99
|
-
"#{(time_difference / 86400).to_i}d ago"
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# @return [String]
|
|
104
|
-
def description_title
|
|
105
|
-
case color
|
|
106
|
-
when RED
|
|
107
|
-
if locked? && failures.empty?
|
|
108
|
-
"Locked Open"
|
|
109
|
-
else
|
|
110
|
-
"Last Error"
|
|
111
|
-
end
|
|
112
|
-
when Stoplight::Color::YELLOW
|
|
113
|
-
"Testing Recovery"
|
|
114
|
-
when GREEN
|
|
115
|
-
if locked?
|
|
116
|
-
"Forced Healthy"
|
|
117
|
-
else
|
|
118
|
-
"Healthy"
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# @return [String]
|
|
124
|
-
def description_message
|
|
125
|
-
case color
|
|
126
|
-
when RED
|
|
127
|
-
if latest_failure
|
|
128
|
-
"#{latest_failure.error_class}: #{latest_failure.error_message}"
|
|
129
|
-
elsif locked?
|
|
130
|
-
"Circuit manually locked open"
|
|
131
|
-
else
|
|
132
|
-
"Not available"
|
|
133
|
-
end
|
|
134
|
-
when Stoplight::Color::YELLOW
|
|
135
|
-
if latest_failure
|
|
136
|
-
"#{latest_failure.error_class}: #{latest_failure.error_message}"
|
|
137
|
-
else
|
|
138
|
-
"Not available"
|
|
139
|
-
end
|
|
140
|
-
when GREEN
|
|
141
|
-
if locked?
|
|
142
|
-
"Circuit manually locked closed"
|
|
143
|
-
else
|
|
144
|
-
"No recent errors"
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# @return [String]
|
|
150
|
-
def description_comment
|
|
151
|
-
case color
|
|
152
|
-
when RED
|
|
153
|
-
if locked?
|
|
154
|
-
"Override active - all requests blocked"
|
|
155
|
-
else
|
|
156
|
-
"Will attempt recovery after cooling period"
|
|
157
|
-
end
|
|
158
|
-
when YELLOW
|
|
159
|
-
"Allowing limited test traffic (0 of 1 requests)"
|
|
160
|
-
when GREEN
|
|
161
|
-
if locked?
|
|
162
|
-
"Override active - all requests processed"
|
|
163
|
-
else
|
|
164
|
-
"Operating normally"
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
end
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
class Admin
|
|
5
|
-
class LightsRepository
|
|
6
|
-
# @!attribute data_store
|
|
7
|
-
# @return [Stoplight::Domain::_DataStore]
|
|
8
|
-
attr_reader :data_store
|
|
9
|
-
private :data_store
|
|
10
|
-
|
|
11
|
-
# @param data_store [Stoplight::Domain::_DataStore]
|
|
12
|
-
def initialize(data_store:)
|
|
13
|
-
@data_store = data_store
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# @return [<Stoplight::Admin::LightsRepository::Light>]
|
|
17
|
-
def all
|
|
18
|
-
data_store
|
|
19
|
-
.names
|
|
20
|
-
.map { |name| load_light(name) }
|
|
21
|
-
.sort_by(&:default_sort_key)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# @param colors <String>] colors name
|
|
25
|
-
# @return [<Stoplight::Admin::LightsRepository::Light>] lights with the requested colors
|
|
26
|
-
#
|
|
27
|
-
def with_color(*colors)
|
|
28
|
-
requested_colors = Array(colors)
|
|
29
|
-
|
|
30
|
-
all.select do |light|
|
|
31
|
-
requested_colors.include?(light.color)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# @param name [String] locks light by its name
|
|
36
|
-
# @param color [String, nil] locks to this color. When nil is given, locks to the current
|
|
37
|
-
# color
|
|
38
|
-
# @return [void]
|
|
39
|
-
def lock(name, color = nil)
|
|
40
|
-
config = build_config(name)
|
|
41
|
-
color ||= data_store.get_state_snapshot(config).color
|
|
42
|
-
|
|
43
|
-
case color
|
|
44
|
-
when Stoplight::Color::GREEN
|
|
45
|
-
data_store.set_state(config, Stoplight::State::LOCKED_GREEN)
|
|
46
|
-
else
|
|
47
|
-
data_store.set_state(config, Stoplight::State::LOCKED_RED)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# @param name [String] unlocks light by its name
|
|
52
|
-
# @return [void]
|
|
53
|
-
def unlock(name)
|
|
54
|
-
config = build_config(name)
|
|
55
|
-
data_store.set_state(config, State::UNLOCKED)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# @param name [String] removes light metadata by its name
|
|
59
|
-
# @return [void]
|
|
60
|
-
def remove(name)
|
|
61
|
-
config = build_config(name)
|
|
62
|
-
|
|
63
|
-
data_store.delete_light(config)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
private def load_light(name)
|
|
67
|
-
config = build_config(name)
|
|
68
|
-
|
|
69
|
-
# failures, state
|
|
70
|
-
state_snapshot = data_store.get_state_snapshot(config)
|
|
71
|
-
metrics = data_store.get_metrics(config)
|
|
72
|
-
|
|
73
|
-
Light.new(
|
|
74
|
-
name: name,
|
|
75
|
-
color: state_snapshot.color,
|
|
76
|
-
state: state_snapshot.locked_state,
|
|
77
|
-
failures: [metrics.last_error].compact,
|
|
78
|
-
failure_count: metrics.consecutive_errors
|
|
79
|
-
)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
private def build_config(name)
|
|
83
|
-
Wiring::DefaultConfig.with(name:)
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "forwardable"
|
|
4
|
-
|
|
5
|
-
module Stoplight
|
|
6
|
-
module Domain
|
|
7
|
-
class Light
|
|
8
|
-
# Implements light configuration behavior
|
|
9
|
-
# steep:ignore:start
|
|
10
|
-
module ConfigurationBuilderInterface
|
|
11
|
-
# Configures data store to be used with this circuit breaker
|
|
12
|
-
#
|
|
13
|
-
# @example
|
|
14
|
-
# Stoplight('example')
|
|
15
|
-
# .with_data_store(Stoplight::DataStore::Memory.new)
|
|
16
|
-
#
|
|
17
|
-
# @param data_store [DataStore::Base]
|
|
18
|
-
# @return [Stoplight::Light]
|
|
19
|
-
# @deprecated
|
|
20
|
-
def with_data_store(data_store)
|
|
21
|
-
deprecate(<<~MSG)
|
|
22
|
-
Light#with_data_store is deprecated and will be removed in v6.0.0.
|
|
23
|
-
|
|
24
|
-
Circuit breakers should be configured once at creation, not cloned with
|
|
25
|
-
modifications.
|
|
26
|
-
|
|
27
|
-
Instead of:
|
|
28
|
-
light = Stoplight('api-call')
|
|
29
|
-
modified = light.with_data_store(data_stare)
|
|
30
|
-
|
|
31
|
-
Configure correctly from the start:
|
|
32
|
-
Stoplight('api-call', data_store:)
|
|
33
|
-
MSG
|
|
34
|
-
with_without_warning(data_store:)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Configures cool off time. Stoplight automatically tries to recover
|
|
38
|
-
# from the red state after the cool off time.
|
|
39
|
-
#
|
|
40
|
-
# @example
|
|
41
|
-
# Stoplight('example')
|
|
42
|
-
# .cool_off_time(60)
|
|
43
|
-
#
|
|
44
|
-
# @param cool_off_time [Numeric] number of seconds
|
|
45
|
-
# @return [Stoplight::Light]
|
|
46
|
-
# @deprecated
|
|
47
|
-
def with_cool_off_time(cool_off_time)
|
|
48
|
-
deprecate(<<~MSG)
|
|
49
|
-
Light#with_cool_off_time is deprecated and will be removed in v6.0.0.
|
|
50
|
-
|
|
51
|
-
Circuit breakers should be configured once at creation, not cloned with
|
|
52
|
-
modifications.
|
|
53
|
-
|
|
54
|
-
Instead of:
|
|
55
|
-
light = Stoplight('api-call')
|
|
56
|
-
modified = light.with_cool_off_time(cool_off_time)
|
|
57
|
-
|
|
58
|
-
Configure correctly from the start:
|
|
59
|
-
Stoplight('api-call', cool_off_time:)
|
|
60
|
-
MSG
|
|
61
|
-
with_without_warning(cool_off_time:)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Configures custom threshold. After this number of failures Stoplight
|
|
65
|
-
# switches to the red state:
|
|
66
|
-
#
|
|
67
|
-
# @example
|
|
68
|
-
# Stoplight('example')
|
|
69
|
-
# .with_threshold(5)
|
|
70
|
-
#
|
|
71
|
-
# @param threshold [Numeric]
|
|
72
|
-
# @return [Stoplight::Light]
|
|
73
|
-
# @deprecated
|
|
74
|
-
def with_threshold(threshold)
|
|
75
|
-
deprecate(<<~MSG)
|
|
76
|
-
Light#with_threshold is deprecated and will be removed in v6.0.0.
|
|
77
|
-
|
|
78
|
-
Circuit breakers should be configured once at creation, not cloned with
|
|
79
|
-
modifications.
|
|
80
|
-
|
|
81
|
-
Instead of:
|
|
82
|
-
light = Stoplight('api-call')
|
|
83
|
-
modified = light.with_threshold(threshold)
|
|
84
|
-
|
|
85
|
-
Configure correctly from the start:
|
|
86
|
-
Stoplight('api-call', threshold:)
|
|
87
|
-
MSG
|
|
88
|
-
with_without_warning(threshold:)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# Configures custom window size which Stoplight uses to count failures. For example,
|
|
92
|
-
#
|
|
93
|
-
# @example
|
|
94
|
-
# Stoplight('example')
|
|
95
|
-
# .with_threshold(5)
|
|
96
|
-
# .with_window_size(60)
|
|
97
|
-
#
|
|
98
|
-
# The above example will turn to red light only when 5 errors happen
|
|
99
|
-
# within 60 seconds period.
|
|
100
|
-
#
|
|
101
|
-
# @param window_size [Numeric] number of seconds
|
|
102
|
-
# @return [Stoplight::Light]
|
|
103
|
-
# @deprecated
|
|
104
|
-
def with_window_size(window_size)
|
|
105
|
-
deprecate(<<~MSG)
|
|
106
|
-
Light#with_window_size is deprecated and will be removed in v6.0.0.
|
|
107
|
-
|
|
108
|
-
Circuit breakers should be configured once at creation, not cloned with
|
|
109
|
-
modifications.
|
|
110
|
-
|
|
111
|
-
Instead of:
|
|
112
|
-
light = Stoplight('api-call')
|
|
113
|
-
modified = light.with_window_size(window_size)
|
|
114
|
-
|
|
115
|
-
Configure correctly from the start:
|
|
116
|
-
Stoplight('api-call', window_size:)
|
|
117
|
-
MSG
|
|
118
|
-
with_without_warning(window_size:)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
# Configures custom notifier
|
|
122
|
-
#
|
|
123
|
-
# @example
|
|
124
|
-
# io = StringIO.new
|
|
125
|
-
# notifier = Stoplight::Notifier::IO.new(io)
|
|
126
|
-
# Stoplight('example')
|
|
127
|
-
# .with_notifiers([notifier])
|
|
128
|
-
#
|
|
129
|
-
# @param notifiers [Array<Notifier::Base>]
|
|
130
|
-
# @return [Stoplight::Light]
|
|
131
|
-
# @deprecated
|
|
132
|
-
def with_notifiers(notifiers)
|
|
133
|
-
deprecate(<<~MSG)
|
|
134
|
-
Light#with_notifiers is deprecated and will be removed in v6.0.0.
|
|
135
|
-
|
|
136
|
-
Circuit breakers should be configured once at creation, not cloned with
|
|
137
|
-
modifications.
|
|
138
|
-
|
|
139
|
-
Instead of:
|
|
140
|
-
light = Stoplight('api-call')
|
|
141
|
-
modified = light.with_notifiers(notifiers)
|
|
142
|
-
|
|
143
|
-
Configure correctly from the start:
|
|
144
|
-
Stoplight('api-call', notifiers:)
|
|
145
|
-
MSG
|
|
146
|
-
with_without_warning(notifiers:)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# @param error_notifier [Proc]
|
|
150
|
-
# @return [Stoplight::Light]
|
|
151
|
-
# @api private
|
|
152
|
-
# @deprecated
|
|
153
|
-
def with_error_notifier(&error_notifier)
|
|
154
|
-
deprecate(<<~MSG)
|
|
155
|
-
Light#with_error_notifier is deprecated and will be removed in v6.0.0.
|
|
156
|
-
|
|
157
|
-
Circuit breakers should be configured once at creation, not cloned with
|
|
158
|
-
modifications.
|
|
159
|
-
|
|
160
|
-
Instead of:
|
|
161
|
-
light = Stoplight('api-call')
|
|
162
|
-
modified = light.with_error_notifier { |error| warn error }
|
|
163
|
-
|
|
164
|
-
Configure correctly from the start:
|
|
165
|
-
Stoplight('api-call', error_notifier: ->(error) { warn error })
|
|
166
|
-
MSG
|
|
167
|
-
with_without_warning(error_notifier: error_notifier)
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
# Configures a custom list of tracked errors that counts toward the threshold.
|
|
171
|
-
#
|
|
172
|
-
# @example
|
|
173
|
-
# light = Stoplight('example')
|
|
174
|
-
# .with_tracked_errors(TimeoutError, NetworkError)
|
|
175
|
-
# light.run { call_external_service }
|
|
176
|
-
#
|
|
177
|
-
# In the example above, the +TimeoutError+ and +NetworkError+ exceptions
|
|
178
|
-
# will be counted towards the threshold for moving the circuit breaker into the red state.
|
|
179
|
-
# If not configured, the default tracked error is +StandardError+.
|
|
180
|
-
#
|
|
181
|
-
# @param tracked_errors [Array<StandardError>]
|
|
182
|
-
# @return [Stoplight::Light]
|
|
183
|
-
# @deprecated
|
|
184
|
-
def with_tracked_errors(*tracked_errors)
|
|
185
|
-
deprecate(<<~MSG)
|
|
186
|
-
Light#with_tracked_errors is deprecated and will be removed in v6.0.0.
|
|
187
|
-
|
|
188
|
-
Circuit breakers should be configured once at creation, not cloned with
|
|
189
|
-
modifications.
|
|
190
|
-
|
|
191
|
-
Instead of:
|
|
192
|
-
light = Stoplight('api-call')
|
|
193
|
-
modified = light.with_tracked_errors(TimeoutError, NetworkError)
|
|
194
|
-
|
|
195
|
-
Configure correctly from the start:
|
|
196
|
-
Stoplight('api-call', tracked_errors: [TimeoutError, NetworkError])
|
|
197
|
-
MSG
|
|
198
|
-
with_without_warning(tracked_errors:)
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
# Configures a custom list of skipped errors that do not count toward the threshold.
|
|
202
|
-
# Typically, such errors does not represent a real failure and handled somewhere else
|
|
203
|
-
# in the code.
|
|
204
|
-
#
|
|
205
|
-
# @example
|
|
206
|
-
# light = Stoplight('example')
|
|
207
|
-
# .with_skipped_errors(ActiveRecord::RecordNotFound)
|
|
208
|
-
# light.run { User.find(123) }
|
|
209
|
-
#
|
|
210
|
-
# In the example above, the +ActiveRecord::RecordNotFound+ doesn't
|
|
211
|
-
# move the circuit breaker into the red state.
|
|
212
|
-
#
|
|
213
|
-
# @param skipped_errors [Array<Exception>]
|
|
214
|
-
# @return [Stoplight::Light]
|
|
215
|
-
# @deprecated
|
|
216
|
-
def with_skipped_errors(*skipped_errors)
|
|
217
|
-
deprecate(<<~MSG)
|
|
218
|
-
Light#with_skipped_errors is deprecated and will be removed in v6.0.0.
|
|
219
|
-
|
|
220
|
-
Circuit breakers should be configured once at creation, not cloned with
|
|
221
|
-
modifications.
|
|
222
|
-
|
|
223
|
-
Instead of:
|
|
224
|
-
light = Stoplight('api-call')
|
|
225
|
-
modified = light.with_skipped_errors(ActiveRecord::RecordNotFound)
|
|
226
|
-
|
|
227
|
-
Configure correctly from the start:
|
|
228
|
-
Stoplight('api-call', skipped_errors: [ActiveRecord::RecordNotFound])
|
|
229
|
-
MSG
|
|
230
|
-
with_without_warning(skipped_errors:)
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
# steep:ignore:end
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
end
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "securerandom"
|
|
4
|
-
|
|
5
|
-
module Stoplight
|
|
6
|
-
module Infrastructure
|
|
7
|
-
module FailSafe
|
|
8
|
-
# A wrapper around a data store that provides fail-safe mechanisms using a
|
|
9
|
-
# circuit breaker. It ensures that operations on the data store can gracefully
|
|
10
|
-
# handle failures by falling back to default values when necessary.
|
|
11
|
-
#
|
|
12
|
-
# @api private
|
|
13
|
-
# steep:ignore:start
|
|
14
|
-
class DataStore
|
|
15
|
-
# The underlying primary data store being used
|
|
16
|
-
attr_reader :data_store
|
|
17
|
-
attr_reader :error_notifier
|
|
18
|
-
# The fallback data store used when the primary fails.
|
|
19
|
-
attr_reader :failover_data_store
|
|
20
|
-
# The circuit breaker used to handle data store failures.
|
|
21
|
-
private attr_reader :circuit_breaker
|
|
22
|
-
|
|
23
|
-
def initialize(data_store:, error_notifier:, failover_data_store:, circuit_breaker:)
|
|
24
|
-
@data_store = data_store
|
|
25
|
-
@error_notifier = error_notifier
|
|
26
|
-
@failover_data_store = failover_data_store
|
|
27
|
-
@circuit_breaker = circuit_breaker
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def names
|
|
31
|
-
with_fallback(:names) do
|
|
32
|
-
data_store.names
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def get_metrics(config)
|
|
37
|
-
with_fallback(:get_metrics, config) do
|
|
38
|
-
data_store.get_metrics(config)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def get_recovery_metrics(config)
|
|
43
|
-
with_fallback(:get_recovery_metrics, config) do
|
|
44
|
-
data_store.get_recovery_metrics(config)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def get_state_snapshot(config)
|
|
49
|
-
with_fallback(:get_state_snapshot, config) do
|
|
50
|
-
data_store.get_state_snapshot(config)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def clear_metrics(config)
|
|
55
|
-
with_fallback(:clear_metrics, config) do
|
|
56
|
-
data_store.clear_metrics(config)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def clear_recovery_metrics(config)
|
|
61
|
-
with_fallback(:clear_recovery_metrics, config) do
|
|
62
|
-
data_store.clear_recovery_metrics(config)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def record_failure(config, exception)
|
|
67
|
-
with_fallback(:record_failure, config, exception) do
|
|
68
|
-
data_store.record_failure(config, exception)
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def record_success(config)
|
|
73
|
-
with_fallback(:record_success, config) do
|
|
74
|
-
data_store.record_success(config)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def record_recovery_probe_success(config)
|
|
79
|
-
with_fallback(:record_recovery_probe_success, config) do
|
|
80
|
-
data_store.record_recovery_probe_success(config)
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def record_recovery_probe_failure(config, exception)
|
|
85
|
-
with_fallback(:record_recovery_probe_failure, config, exception) do
|
|
86
|
-
data_store.record_recovery_probe_failure(config, exception)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def set_state(config, state)
|
|
91
|
-
with_fallback(:set_state, config, state) do
|
|
92
|
-
data_store.set_state(config, state)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def transition_to_color(config, color)
|
|
97
|
-
with_fallback(:transition_to_color, config, color) do
|
|
98
|
-
data_store.transition_to_color(config, color)
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def delete_light(config)
|
|
103
|
-
with_fallback(:delete_light, config) do
|
|
104
|
-
data_store.delete_light(config)
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# @param config [Stoplight::Domain::Config]
|
|
109
|
-
def acquire_recovery_lock(config)
|
|
110
|
-
with_fallback(:acquire_recovery_lock, config) do
|
|
111
|
-
data_store.acquire_recovery_lock(config)
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# Routes release to correct store based on token type.
|
|
116
|
-
# Redis tokens release via primary (with error notification on failure).
|
|
117
|
-
# Memory tokens release via failover directly.
|
|
118
|
-
#
|
|
119
|
-
def release_recovery_lock(recovery_lock_token)
|
|
120
|
-
case recovery_lock_token
|
|
121
|
-
in Redis::DataStore::RecoveryLockToken
|
|
122
|
-
fallback = proc do |error|
|
|
123
|
-
error_notifier.call(error) if error
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
circuit_breaker.run(fallback) do
|
|
127
|
-
data_store.release_recovery_lock(recovery_lock_token)
|
|
128
|
-
end
|
|
129
|
-
in Memory::DataStore::RecoveryLockToken
|
|
130
|
-
failover_data_store.release_recovery_lock(recovery_lock_token)
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def ==(other)
|
|
135
|
-
other.is_a?(self.class) && other.data_store == data_store && other.error_notifier == error_notifier &&
|
|
136
|
-
other.failover_data_store == failover_data_store
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
private def with_fallback(method_name, *args, **kwargs, &code)
|
|
140
|
-
fallback = ->(error) {
|
|
141
|
-
config = args.first
|
|
142
|
-
error_notifier.call(error) if config && error
|
|
143
|
-
failover_data_store.public_send(method_name, *args, **kwargs)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
circuit_breaker.run(fallback, &code)
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
# steep:ignore:end
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
end
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Stoplight
|
|
4
|
-
module Infrastructure
|
|
5
|
-
module Memory
|
|
6
|
-
class DataStore
|
|
7
|
-
class Metrics
|
|
8
|
-
attr_accessor :consecutive_errors
|
|
9
|
-
attr_accessor :consecutive_successes
|
|
10
|
-
attr_accessor :last_error
|
|
11
|
-
attr_accessor :last_success_at
|
|
12
|
-
|
|
13
|
-
def initialize(consecutive_errors: 0, consecutive_successes: 0, last_error: nil, last_success_at: nil)
|
|
14
|
-
@consecutive_errors = consecutive_errors
|
|
15
|
-
@consecutive_successes = consecutive_successes
|
|
16
|
-
@last_error = last_error
|
|
17
|
-
@last_success_at = last_success_at
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def last_error_at
|
|
21
|
-
@last_error&.time
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|