stoplight 5.7.0 → 5.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/UPGRADING.md +303 -0
- data/lib/generators/stoplight/install/install_generator.rb +6 -1
- data/lib/stoplight/admin/dependencies.rb +1 -1
- data/lib/stoplight/admin/helpers.rb +20 -4
- data/lib/stoplight/admin/lights_repository/light.rb +22 -6
- data/lib/stoplight/admin/lights_repository.rb +6 -5
- data/lib/stoplight/admin/views/_card.erb +8 -5
- data/lib/stoplight/color.rb +9 -0
- data/lib/stoplight/data_store.rb +28 -0
- data/lib/stoplight/domain/compatibility_result.rb +7 -7
- data/lib/stoplight/domain/config.rb +38 -39
- data/lib/stoplight/domain/error_tracking_policy.rb +27 -0
- data/lib/stoplight/domain/failure.rb +1 -1
- data/lib/stoplight/domain/light/configuration_builder_interface.rb +2 -0
- data/lib/stoplight/domain/light.rb +15 -46
- data/lib/stoplight/domain/light_info.rb +7 -0
- data/lib/stoplight/domain/metrics_snapshot.rb +58 -0
- data/lib/stoplight/domain/state_snapshot.rb +29 -23
- data/lib/stoplight/domain/storage/recovery_lock_token.rb +15 -0
- data/lib/stoplight/domain/strategies/green_run_strategy.rb +18 -26
- data/lib/stoplight/domain/strategies/red_run_strategy.rb +9 -12
- data/lib/stoplight/domain/strategies/yellow_run_strategy.rb +41 -51
- data/lib/stoplight/domain/tracker/recovery_probe.rb +16 -33
- data/lib/stoplight/domain/tracker/request.rb +12 -31
- data/lib/stoplight/domain/traffic_control/consecutive_errors.rb +8 -11
- data/lib/stoplight/domain/traffic_control/error_rate.rb +19 -15
- data/lib/stoplight/domain/traffic_recovery/consecutive_successes.rb +6 -10
- data/lib/stoplight/domain/traffic_recovery.rb +3 -4
- data/lib/stoplight/error.rb +46 -0
- data/lib/stoplight/infrastructure/{data_store/fail_safe.rb → fail_safe/data_store.rb} +39 -51
- data/lib/stoplight/infrastructure/fail_safe/storage/metrics.rb +65 -0
- data/lib/stoplight/infrastructure/fail_safe/storage/recovery_lock.rb +69 -0
- data/lib/stoplight/infrastructure/fail_safe/storage/recovery_lock_token.rb +19 -0
- data/lib/stoplight/infrastructure/fail_safe/storage/state.rb +62 -0
- data/lib/stoplight/infrastructure/{data_store/memory → memory/data_store}/metrics.rb +2 -2
- data/lib/stoplight/infrastructure/{data_store/memory → memory/data_store}/recovery_lock_store.rb +10 -12
- data/lib/stoplight/infrastructure/{data_store/memory → memory/data_store}/recovery_lock_token.rb +3 -6
- data/lib/stoplight/infrastructure/{data_store/memory → memory/data_store}/sliding_window.rb +21 -26
- data/lib/stoplight/infrastructure/{data_store/memory → memory/data_store}/state.rb +3 -3
- data/lib/stoplight/infrastructure/{data_store/memory.rb → memory/data_store.rb} +36 -32
- data/lib/stoplight/infrastructure/memory/storage/recovery_lock.rb +35 -0
- data/lib/stoplight/infrastructure/memory/storage/recovery_metrics.rb +16 -0
- data/lib/stoplight/infrastructure/memory/storage/state.rb +155 -0
- data/lib/stoplight/infrastructure/memory/storage/unbounded_metrics.rb +103 -0
- data/lib/stoplight/infrastructure/memory/storage/window_metrics.rb +101 -0
- data/lib/stoplight/infrastructure/notifier/fail_safe.rb +9 -21
- data/lib/stoplight/infrastructure/notifier/generic.rb +4 -14
- data/lib/stoplight/infrastructure/notifier/io.rb +1 -2
- data/lib/stoplight/infrastructure/notifier/logger.rb +1 -2
- data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/recovery_lock_store.rb +9 -22
- data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/recovery_lock_token.rb +7 -14
- data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/scripting.rb +22 -20
- data/lib/stoplight/infrastructure/{data_store/redis.rb → redis/data_store.rb} +47 -55
- data/lib/stoplight/infrastructure/redis/storage/key_space.rb +51 -0
- data/lib/stoplight/infrastructure/redis/storage/metrics.rb +40 -0
- data/lib/stoplight/infrastructure/redis/storage/recovery_lock/release_lock.lua +6 -0
- data/lib/stoplight/infrastructure/redis/storage/recovery_lock.rb +64 -0
- data/lib/stoplight/infrastructure/redis/storage/recovery_metrics.rb +20 -0
- data/lib/stoplight/infrastructure/redis/storage/scripting.rb +18 -0
- data/lib/stoplight/infrastructure/redis/storage/state/transition_to_green.lua +10 -0
- data/lib/stoplight/infrastructure/redis/storage/state/transition_to_red.lua +10 -0
- data/lib/stoplight/infrastructure/redis/storage/state/transition_to_yellow.lua +9 -0
- data/lib/stoplight/infrastructure/redis/storage/state.rb +141 -0
- data/lib/stoplight/infrastructure/redis/storage/unbounded_metrics/record_failure.lua +28 -0
- data/lib/stoplight/infrastructure/redis/storage/unbounded_metrics/record_success.lua +26 -0
- data/lib/stoplight/infrastructure/redis/storage/unbounded_metrics.rb +123 -0
- data/lib/stoplight/infrastructure/redis/storage/window_metrics/metrics_snapshot.lua +26 -0
- data/lib/stoplight/infrastructure/redis/storage/window_metrics/record_failure.lua +36 -0
- data/lib/stoplight/infrastructure/redis/storage/window_metrics/record_success.lua +35 -0
- data/lib/stoplight/infrastructure/redis/storage/window_metrics.rb +174 -0
- data/lib/stoplight/infrastructure/storage/compatibility_metrics.rb +3 -10
- data/lib/stoplight/infrastructure/storage/compatibility_recovery_lock.rb +8 -11
- data/lib/stoplight/infrastructure/storage/compatibility_recovery_metrics.rb +6 -14
- data/lib/stoplight/infrastructure/storage/compatibility_state.rb +6 -17
- data/lib/stoplight/infrastructure/system_clock.rb +16 -0
- data/lib/stoplight/notifier.rb +11 -0
- data/lib/stoplight/state.rb +9 -0
- data/lib/stoplight/types.rb +29 -0
- data/lib/stoplight/undefined.rb +16 -0
- data/lib/stoplight/version.rb +1 -1
- data/lib/stoplight/wiring/config_compatibility_validator.rb +54 -0
- data/lib/stoplight/wiring/configuration_dsl.rb +101 -0
- data/lib/stoplight/wiring/data_store_backend.rb +26 -0
- data/lib/stoplight/wiring/default.rb +1 -1
- data/lib/stoplight/wiring/default_config.rb +21 -0
- data/lib/stoplight/wiring/default_configuration.rb +70 -53
- data/lib/stoplight/wiring/light_builder.rb +76 -63
- data/lib/stoplight/wiring/light_factory/traffic_control_dsl.rb +3 -3
- data/lib/stoplight/wiring/light_factory/traffic_recovery_dsl.rb +4 -4
- data/lib/stoplight/wiring/light_factory.rb +78 -52
- data/lib/stoplight/wiring/memory/backend.rb +57 -0
- data/lib/stoplight/wiring/redis/backend.rb +116 -0
- data/lib/stoplight/wiring/storage_set.rb +12 -0
- data/lib/stoplight/wiring/storage_set_builder.rb +51 -0
- data/lib/stoplight/wiring/system/light_builder.rb +47 -0
- data/lib/stoplight/wiring/system/light_factory.rb +64 -0
- data/lib/stoplight/wiring/system.rb +129 -0
- data/lib/stoplight.rb +196 -25
- data/sig/_private/generators/stoplight/install/install_generator.rbs +22 -0
- data/sig/_private/stoplight/common/deprecations.rbs +9 -0
- data/sig/_private/stoplight/data_store.rbs +6 -0
- data/sig/_private/stoplight/domain/compatibility_result.rbs +18 -0
- data/sig/_private/stoplight/domain/config.rbs +65 -0
- data/sig/_private/stoplight/domain/error_tracking_policy.rbs +14 -0
- data/sig/_private/stoplight/domain/failure.rbs +16 -0
- data/sig/_private/stoplight/domain/light.rbs +25 -0
- data/sig/_private/stoplight/domain/light_info.rbs +19 -0
- data/sig/_private/stoplight/domain/metrics_snapshot.rbs +38 -0
- data/sig/_private/stoplight/domain/ports/clock.rbs +18 -0
- data/sig/_private/stoplight/domain/ports/data_store.rbs +76 -0
- data/{lib/stoplight/domain/light_factory.rb → sig/_private/stoplight/domain/ports/light_factory.rbs} +33 -28
- data/sig/_private/stoplight/domain/ports/metrics_store.rbs +29 -0
- data/sig/_private/stoplight/domain/ports/recovery_lock_store.rbs +52 -0
- data/sig/_private/stoplight/domain/ports/recovery_lock_token.rbs +6 -0
- data/sig/_private/stoplight/domain/ports/run_strategy.rbs +14 -0
- data/sig/_private/stoplight/domain/ports/state_store.rbs +79 -0
- data/sig/_private/stoplight/domain/ports/traffic_control.rbs +41 -0
- data/sig/_private/stoplight/domain/ports/traffic_recovery.rbs +47 -0
- data/sig/_private/stoplight/domain/state_snapshot.rbs +32 -0
- data/sig/_private/stoplight/domain/storage/recovery_lock_token.rbs +11 -0
- data/sig/_private/stoplight/domain/strategies/green_run_strategy.rbs +17 -0
- data/sig/_private/stoplight/domain/strategies/red_run_strategy.rbs +17 -0
- data/sig/_private/stoplight/domain/strategies/yellow_run_strategy.rbs +42 -0
- data/{lib/stoplight/domain/tracker/base.rb → sig/_private/stoplight/domain/tracker/base.rbs} +0 -4
- data/sig/_private/stoplight/domain/tracker/recovery_probe.rbs +25 -0
- data/sig/_private/stoplight/domain/tracker/request.rbs +26 -0
- data/sig/_private/stoplight/domain/traffic_control/consecutive_errors.rbs +9 -0
- data/sig/_private/stoplight/domain/traffic_control/error_rate.rbs +13 -0
- data/sig/_private/stoplight/domain/traffic_recovery/consecutive_successes.rbs +9 -0
- data/sig/_private/stoplight/domain/traffic_recovery.rbs +9 -0
- data/sig/_private/stoplight/infrastructure/fail_safe/data_store.rbs +26 -0
- data/sig/_private/stoplight/infrastructure/fail_safe/storage/metrics.rbs +25 -0
- data/sig/_private/stoplight/infrastructure/fail_safe/storage/recovery_lock.rbs +29 -0
- data/sig/_private/stoplight/infrastructure/fail_safe/storage/recovery_lock_token.rbs +19 -0
- data/sig/_private/stoplight/infrastructure/fail_safe/storage/state.rbs +25 -0
- data/sig/_private/stoplight/infrastructure/memory/data_store/metrics.rbs +25 -0
- data/sig/_private/stoplight/infrastructure/memory/data_store/recovery_lock_store.rbs +19 -0
- data/sig/_private/stoplight/infrastructure/memory/data_store/recovery_lock_token.rbs +17 -0
- data/sig/_private/stoplight/infrastructure/memory/data_store/sliding_window.rbs +27 -0
- data/sig/_private/stoplight/infrastructure/memory/data_store/state.rbs +17 -0
- data/sig/_private/stoplight/infrastructure/memory/data_store.rbs +30 -0
- data/sig/_private/stoplight/infrastructure/memory/storage/recovery_lock.rbs +15 -0
- data/sig/_private/stoplight/infrastructure/memory/storage/recovery_metrics.rbs +10 -0
- data/sig/_private/stoplight/infrastructure/memory/storage/state.rbs +28 -0
- data/sig/_private/stoplight/infrastructure/memory/storage/unbounded_metrics.rbs +25 -0
- data/sig/_private/stoplight/infrastructure/memory/storage/window_metrics.rbs +26 -0
- data/sig/_private/stoplight/infrastructure/notifier/fail_safe.rbs +17 -0
- data/sig/_private/stoplight/infrastructure/notifier/generic.rbs +18 -0
- data/sig/_private/stoplight/infrastructure/notifier/io.rbs +14 -0
- data/sig/_private/stoplight/infrastructure/notifier/logger.rbs +14 -0
- data/sig/_private/stoplight/infrastructure/redis/data_store/recovery_lock_store.rbs +24 -0
- data/sig/_private/stoplight/infrastructure/redis/data_store/recovery_lock_token.rbs +21 -0
- data/sig/_private/stoplight/infrastructure/redis/data_store/scripting.rbs +34 -0
- data/sig/_private/stoplight/infrastructure/redis/data_store.rbs +67 -0
- data/sig/_private/stoplight/infrastructure/redis/storage/key_space.rbs +19 -0
- data/sig/_private/stoplight/infrastructure/redis/storage/metrics.rbs +17 -0
- data/sig/_private/stoplight/infrastructure/redis/storage/recovery_lock.rbs +26 -0
- data/sig/_private/stoplight/infrastructure/redis/storage/recovery_metrics.rbs +10 -0
- data/sig/_private/stoplight/infrastructure/redis/storage/scripting.rbs +13 -0
- data/sig/_private/stoplight/infrastructure/redis/storage/state.rbs +32 -0
- data/sig/_private/stoplight/infrastructure/redis/storage/unbounded_metrics.rbs +21 -0
- data/sig/_private/stoplight/infrastructure/redis/storage/window_metrics.rbs +34 -0
- data/sig/_private/stoplight/infrastructure/storage/compatibility_metrics.rbs +17 -0
- data/sig/_private/stoplight/infrastructure/storage/compatibility_recovery_lock.rbs +13 -0
- data/sig/_private/stoplight/infrastructure/storage/compatibility_recovery_metrics.rbs +14 -0
- data/sig/_private/stoplight/infrastructure/storage/compatibility_state.rbs +14 -0
- data/sig/_private/stoplight/infrastructure/system_clock.rbs +7 -0
- data/sig/_private/stoplight/system/light_builder.rbs +23 -0
- data/sig/_private/stoplight/system/light_factory.rbs +17 -0
- data/sig/_private/stoplight/types.rbs +6 -0
- data/sig/_private/stoplight/wiring/config_compatibility_validator.rbs +19 -0
- data/sig/_private/stoplight/wiring/configuration_dsl.rbs +43 -0
- data/sig/_private/stoplight/wiring/data_store_backend.rbs +11 -0
- data/sig/_private/stoplight/wiring/default.rbs +26 -0
- data/{lib/stoplight/wiring/data_store/memory.rb → sig/_private/stoplight/wiring/default_config.rbs} +1 -4
- data/sig/_private/stoplight/wiring/default_configuration.rbs +29 -0
- data/sig/_private/stoplight/wiring/light_builder.rbs +48 -0
- data/sig/_private/stoplight/wiring/light_factory/traffic_control_dsl.rbs +7 -0
- data/sig/_private/stoplight/wiring/light_factory/traffic_recovery_dsl.rbs +7 -0
- data/sig/_private/stoplight/wiring/light_factory.rbs +16 -0
- data/sig/_private/stoplight/wiring/memory/backend.rbs +26 -0
- data/sig/_private/stoplight/wiring/notifier_factory.rbs +10 -0
- data/sig/_private/stoplight/wiring/redis/backend.rbs +38 -0
- data/sig/_private/stoplight/wiring/storage_set.rbs +38 -0
- data/sig/_private/stoplight/wiring/storage_set_builder.rbs +15 -0
- data/sig/_private/stoplight/wiring/system.rbs +15 -0
- data/sig/_private/stoplight.rbs +48 -0
- data/sig/stoplight/color.rbs +7 -0
- data/sig/stoplight/data_store.rbs +19 -0
- data/sig/stoplight/error.rbs +20 -0
- data/sig/stoplight/notifier.rbs +11 -0
- data/sig/stoplight/ports/configuration.rbs +19 -0
- data/sig/stoplight/ports/exception_matcher.rbs +8 -0
- data/sig/stoplight/ports/light.rbs +12 -0
- data/sig/stoplight/ports/light_info.rbs +5 -0
- data/sig/stoplight/ports/state_transition_notifier.rbs +15 -0
- data/sig/stoplight/ports/system.rbs +21 -0
- data/sig/stoplight/state.rbs +7 -0
- data/sig/stoplight/undefined.rbs +9 -0
- data/sig/stoplight/version.rbs +3 -0
- data/sig/stoplight.rbs +66 -0
- metadata +175 -47
- data/lib/stoplight/domain/color.rb +0 -11
- data/lib/stoplight/domain/data_store.rb +0 -146
- data/lib/stoplight/domain/error.rb +0 -42
- data/lib/stoplight/domain/metrics.rb +0 -64
- data/lib/stoplight/domain/recovery_lock_token.rb +0 -15
- data/lib/stoplight/domain/state.rb +0 -11
- data/lib/stoplight/domain/state_transition_notifier.rb +0 -25
- data/lib/stoplight/domain/storage/metrics.rb +0 -42
- data/lib/stoplight/domain/storage/recovery_lock.rb +0 -56
- data/lib/stoplight/domain/storage/state.rb +0 -87
- data/lib/stoplight/domain/strategies/run_strategy.rb +0 -22
- data/lib/stoplight/domain/traffic_control/base.rb +0 -74
- data/lib/stoplight/domain/traffic_recovery/base.rb +0 -79
- data/lib/stoplight/wiring/data_store/base.rb +0 -11
- data/lib/stoplight/wiring/data_store/redis.rb +0 -25
- data/lib/stoplight/wiring/default_factory_builder.rb +0 -25
- data/lib/stoplight/wiring/light/default_config.rb +0 -18
- data/lib/stoplight/wiring/light/system_config.rb +0 -11
- data/lib/stoplight/wiring/light_factory/compatibility_validator.rb +0 -55
- data/lib/stoplight/wiring/light_factory/config_normalizer.rb +0 -71
- data/lib/stoplight/wiring/light_factory/configuration_pipeline.rb +0 -72
- data/lib/stoplight/wiring/public_api.rb +0 -29
- /data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/lua_scripts/get_metrics.lua +0 -0
- /data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/lua_scripts/record_failure.lua +0 -0
- /data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/lua_scripts/record_recovery_probe_failure.lua +0 -0
- /data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/lua_scripts/record_recovery_probe_success.lua +0 -0
- /data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/lua_scripts/record_success.lua +0 -0
- /data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/lua_scripts/release_lock.lua +0 -0
- /data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/lua_scripts/transition_to_green.lua +0 -0
- /data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/lua_scripts/transition_to_red.lua +0 -0
- /data/lib/stoplight/infrastructure/{data_store/redis → redis/data_store}/lua_scripts/transition_to_yellow.lua +0 -0
data/{lib/stoplight/domain/light_factory.rb → sig/_private/stoplight/domain/ports/light_factory.rbs}
RENAMED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
module Stoplight
|
|
4
2
|
module Domain
|
|
5
3
|
# Abstract factory protocol for building +Stoplight::Light+ instances.
|
|
@@ -17,39 +15,36 @@ module Stoplight
|
|
|
17
15
|
# - Different factory implementations can be swapped (code, database-configured, etc.)
|
|
18
16
|
# - Dependency direction is preserved (Application → Domain, not Domain → Application)
|
|
19
17
|
#
|
|
20
|
-
|
|
21
|
-
# @api private
|
|
22
|
-
class LightFactory
|
|
18
|
+
interface _LightFactory
|
|
23
19
|
# Creates a new factory with modified settings.
|
|
24
20
|
#
|
|
25
21
|
# This method must return a NEW factory instance - it should not
|
|
26
22
|
# modify the current factory. The new factory should inherit all
|
|
27
23
|
# configuration from the current factory, with the provided
|
|
28
24
|
# settings overriding specific values.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
def with: (
|
|
26
|
+
?name: optional[String],
|
|
27
|
+
?cool_off_time: optional[duration],
|
|
28
|
+
?threshold: optional[percentage | Integer],
|
|
29
|
+
?recovery_threshold: optional[Integer],
|
|
30
|
+
?window_size: optional[duration?],
|
|
31
|
+
?tracked_errors: optional[Array[_ExceptionMatcher] | _ExceptionMatcher],
|
|
32
|
+
?skipped_errors: optional[Array[_ExceptionMatcher] | _ExceptionMatcher],
|
|
33
|
+
?error_notifier: optional[error_notifier],
|
|
34
|
+
?notifiers: optional[Array[state_transition_notifier]],
|
|
35
|
+
?data_store: optional[data_store],
|
|
36
|
+
?traffic_control: optional[traffic_control],
|
|
37
|
+
?traffic_recovery: optional[traffic_recovery],
|
|
38
|
+
) -> _LightFactory
|
|
38
39
|
|
|
39
|
-
# Builds a
|
|
40
|
+
# Builds a Light instance with the current configuration.
|
|
40
41
|
#
|
|
41
42
|
# This method must construct a fully-wired Light with all required
|
|
42
43
|
# dependencies (strategies, data store, notifiers, etc.). The Light
|
|
43
44
|
# should be ready to use immediately after construction.
|
|
44
45
|
#
|
|
45
|
-
# @return [Stoplight::Light] Configured circuit breaker instance
|
|
46
|
-
# @raise [NotImplementedError] Must be implemented by subclass
|
|
47
46
|
# @raise [Stoplight::Error::ConfigurationError] If configuration is invalid
|
|
48
|
-
|
|
49
|
-
def build
|
|
50
|
-
raise NotImplementedError
|
|
51
|
-
end
|
|
52
|
-
# :nocov:
|
|
47
|
+
def build: -> Light
|
|
53
48
|
|
|
54
49
|
# Convenience method to configure and build in one operation.
|
|
55
50
|
#
|
|
@@ -57,9 +52,6 @@ module Stoplight
|
|
|
57
52
|
# useful when you want to create a customized Light without keeping
|
|
58
53
|
# a reference to the intermediate factory.
|
|
59
54
|
#
|
|
60
|
-
# @param settings [Hash] Settings to override before building
|
|
61
|
-
# @return [Stoplight::Light] Configured circuit breaker instance
|
|
62
|
-
#
|
|
63
55
|
# @example Usage
|
|
64
56
|
# # Instead of:
|
|
65
57
|
# new_factory = factory.with(threshold: 10)
|
|
@@ -67,9 +59,22 @@ module Stoplight
|
|
|
67
59
|
#
|
|
68
60
|
# # You can do:
|
|
69
61
|
# light = factory.build_with(threshold: 10)
|
|
70
|
-
def build_with(
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
def build_with: (
|
|
63
|
+
?name: optional[String],
|
|
64
|
+
?cool_off_time: optional[duration],
|
|
65
|
+
?threshold: optional[percentage | Integer],
|
|
66
|
+
?recovery_threshold: optional[Integer],
|
|
67
|
+
?window_size: optional[duration?],
|
|
68
|
+
?tracked_errors: optional[Array[_ExceptionMatcher] | _ExceptionMatcher],
|
|
69
|
+
?skipped_errors: optional[Array[_ExceptionMatcher] | _ExceptionMatcher],
|
|
70
|
+
?error_notifier: optional[error_notifier],
|
|
71
|
+
?notifiers: optional[Array[state_transition_notifier]],
|
|
72
|
+
?data_store: optional[data_store],
|
|
73
|
+
?traffic_control: optional[traffic_control],
|
|
74
|
+
?traffic_recovery: optional[traffic_recovery],
|
|
75
|
+
) -> Light
|
|
76
|
+
|
|
77
|
+
def ==: (untyped) -> bool
|
|
73
78
|
end
|
|
74
79
|
end
|
|
75
80
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
# Encapsulates metrics storage for circuit breaker execution tracking.
|
|
4
|
+
#
|
|
5
|
+
# This abstraction isolates metrics collection and retrieval from the
|
|
6
|
+
# broader data store concerns, enabling:
|
|
7
|
+
# - Purpose-built implementations optimized for time-series data
|
|
8
|
+
# - Independent scaling and optimization of metrics vs. state storage
|
|
9
|
+
# - Clearer separation between "what happened" (metrics) and "what to do" (state)
|
|
10
|
+
#
|
|
11
|
+
# Lifecycle: A Metrics instance is scoped to a single circuit breaker
|
|
12
|
+
# configuration. Each circuit gets its own metrics store instance,
|
|
13
|
+
# allowing different circuits to use different storage strategies.
|
|
14
|
+
#
|
|
15
|
+
interface _MetricsStore
|
|
16
|
+
# Retrieves a snapshot of current metrics for decision-making.
|
|
17
|
+
def metrics_snapshot: () -> Domain::MetricsSnapshot
|
|
18
|
+
|
|
19
|
+
# Records a successful circuit breaker execution
|
|
20
|
+
def record_success: () -> void
|
|
21
|
+
|
|
22
|
+
# Records a failed circuit breaker execution
|
|
23
|
+
def record_failure: (StandardError error) -> void
|
|
24
|
+
|
|
25
|
+
# Clears all metrics for this circuit
|
|
26
|
+
def clear: () -> void
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Stoplight
|
|
4
|
+
module Domain
|
|
5
|
+
# Encapsulates recovery lock management for coordinating recovery probes.
|
|
6
|
+
#
|
|
7
|
+
# When a circuit enters YELLOW state (half-open), it begins sending
|
|
8
|
+
# "recovery probes" - test requests to check if the protected service
|
|
9
|
+
# has recovered. In distributed deployments with multiple instances,
|
|
10
|
+
# recovery locks ensure only ONE instance sends probes at a time.
|
|
11
|
+
#
|
|
12
|
+
# Without coordination, all instances would simultaneously:
|
|
13
|
+
# 1. Detect the circuit is YELLOW
|
|
14
|
+
# 2. Send recovery probes to the struggling service
|
|
15
|
+
# 3. Potentially overwhelm it with "test" traffic
|
|
16
|
+
#
|
|
17
|
+
# Lock Lifecycle:
|
|
18
|
+
#
|
|
19
|
+
# Instance A: acquire_lock -> probe -> release_lock
|
|
20
|
+
# Instance B: acquire_lock -> nil (already held) -> skip probe
|
|
21
|
+
# Instance C: acquire_lock -> nil (already held) -> skip probe
|
|
22
|
+
#
|
|
23
|
+
# Lock Semantics:
|
|
24
|
+
# - Returns +nil+ if lock is already held. Never blocks waiting for lock availability
|
|
25
|
+
# - Locks must automatically expire when persisted storage is used
|
|
26
|
+
# - Failed releases are acceptable (timeout provides safety)
|
|
27
|
+
#
|
|
28
|
+
# @see Stoplight::Domain::Strategies::YellowRunStrategy
|
|
29
|
+
interface _RecoveryLockStore
|
|
30
|
+
# Attempts to acquire recovery lock for exclusive probe execution.
|
|
31
|
+
#
|
|
32
|
+
# This method tries to acquire a lock that serializes recovery probe
|
|
33
|
+
# execution across multiple instances. If the lock is already held by
|
|
34
|
+
# another instance, returns +nil+ immediately without blocking.
|
|
35
|
+
#
|
|
36
|
+
# @return
|
|
37
|
+
# - +RecoveryLockToken+: Lock acquired, caller should send probe
|
|
38
|
+
# - +nil+: Lock unavailable, another instance is probing
|
|
39
|
+
#
|
|
40
|
+
def acquire_lock: -> Storage::RecoveryLockToken?
|
|
41
|
+
|
|
42
|
+
# Releases a previously acquired lock.
|
|
43
|
+
#
|
|
44
|
+
# This method releases the lock token returned by +#acquire_lock+,
|
|
45
|
+
# allowing other instances to acquire it. Release should be called
|
|
46
|
+
# in an ensure block to guarantee cleanup even if probe fails.
|
|
47
|
+
#
|
|
48
|
+
# @param lock The token returned by +#acquire_lock+
|
|
49
|
+
def release_lock: (Storage::RecoveryLockToken) -> void
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
# Represents an abstract strategy for running a light's operations.
|
|
4
|
+
# Every new strategy should implement this interface
|
|
5
|
+
#
|
|
6
|
+
interface _RunStrategy
|
|
7
|
+
# @param fallback A fallback proc to execute in case of an error.
|
|
8
|
+
def execute: [T] (
|
|
9
|
+
(^(StandardError?) -> T)? fallback,
|
|
10
|
+
state_snapshot: StateSnapshot
|
|
11
|
+
) { () -> T } -> T
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
# Encapsulates circuit breaker state storage.
|
|
4
|
+
#
|
|
5
|
+
# State management handles the current operational mode of a circuit breaker:
|
|
6
|
+
# - Color (GREEN/YELLOW/RED) - whether the circuit is open or closed
|
|
7
|
+
# - Lock state (LOCKED_GREEN/LOCKED_RED/UNLOCKED) - manual overrides
|
|
8
|
+
# - State transitions - tracking color changes for notifications #
|
|
9
|
+
#
|
|
10
|
+
# State requires stronger consistency than metrics because:
|
|
11
|
+
# - Multiple instances must agree on circuit color
|
|
12
|
+
# - Race conditions during transitions must be handled
|
|
13
|
+
# - Lock states must be immediately visible across instances
|
|
14
|
+
#
|
|
15
|
+
interface _StateStore
|
|
16
|
+
# Retrieves current state snapshot for decision-making.
|
|
17
|
+
#
|
|
18
|
+
# The snapshot is an immutable view of the circuit's current state,
|
|
19
|
+
# including its color and lock status. This method is called on every
|
|
20
|
+
# circuit breaker invocation to determine whether to allow traffic.
|
|
21
|
+
#
|
|
22
|
+
# This is called on every request, so implementations should be fast.
|
|
23
|
+
#
|
|
24
|
+
def state_snapshot: () -> StateSnapshot
|
|
25
|
+
|
|
26
|
+
# Sets the lock state of the circuit.
|
|
27
|
+
#
|
|
28
|
+
# Locks allow manual override of circuit behavior:
|
|
29
|
+
# - LOCKED_GREEN: Force circuit closed (allow all traffic)
|
|
30
|
+
# - LOCKED_RED: Force circuit open (block all traffic)
|
|
31
|
+
# - UNLOCKED: Follow normal circuit breaker rules
|
|
32
|
+
#
|
|
33
|
+
# Lock states take precedence over color states. A locked circuit
|
|
34
|
+
# ignores failure thresholds and stays in the locked state until
|
|
35
|
+
# explicitly unlocked.
|
|
36
|
+
#
|
|
37
|
+
# Use Cases:
|
|
38
|
+
# - Emergency traffic control during incidents
|
|
39
|
+
# - Maintenance windows (lock RED to prevent traffic)
|
|
40
|
+
# - Gradual rollout (lock GREEN during testing)
|
|
41
|
+
#
|
|
42
|
+
# @param state The new state to set.
|
|
43
|
+
# @return The state that was set.
|
|
44
|
+
def set_state: (state) -> state
|
|
45
|
+
|
|
46
|
+
# Transitions the Stoplight to the specified color.
|
|
47
|
+
#
|
|
48
|
+
# This method performs a color transition operation that works across distributed instances
|
|
49
|
+
# of the light. It ensures that in a multi-instance environment, only one instance
|
|
50
|
+
# is considered the "first" to perform the transition (and therefore responsible for
|
|
51
|
+
# triggering notifications).
|
|
52
|
+
#
|
|
53
|
+
# @param color The target color/state to transition to.
|
|
54
|
+
# Should be one of Stoplight::Color::GREEN, Stoplight::Color::YELLOW, or Stoplight::Color::RED.
|
|
55
|
+
#
|
|
56
|
+
# @return Returns +true+ if this instance was the first to perform this specific transition
|
|
57
|
+
# (and should therefore trigger notifications). Returns +false+ if another instance already
|
|
58
|
+
# initiated this transition.
|
|
59
|
+
#
|
|
60
|
+
# @note In distributed environments with multiple instances, race conditions can occur when instances
|
|
61
|
+
# attempt conflicting transitions simultaneously (e.g., one instance tries to transition from
|
|
62
|
+
# YELLOW to GREEN while another tries YELLOW to RED). The implementation handles this, but
|
|
63
|
+
# be aware that the last operation may determine the final color of the light.
|
|
64
|
+
#
|
|
65
|
+
def transition_to_color: (color) -> bool
|
|
66
|
+
|
|
67
|
+
# Clears all state data for this circuit.
|
|
68
|
+
#
|
|
69
|
+
# This removes the circuit from storage entirely, resetting it to
|
|
70
|
+
# default (unlocked, green) state. The next invocation will start
|
|
71
|
+
# with fresh state.
|
|
72
|
+
#
|
|
73
|
+
# @note This does NOT clear metrics. If you want to fully
|
|
74
|
+
# reset a circuit, clear both state and metrics stores.
|
|
75
|
+
#
|
|
76
|
+
def clear: () -> void
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
# Strategies for determining when a Stoplight should change color to red.
|
|
4
|
+
#
|
|
5
|
+
# These strategies evaluate the current state and metrics of a Stoplight to decide
|
|
6
|
+
# if traffic should be stopped (i.e., if the light should turn RED).
|
|
7
|
+
#
|
|
8
|
+
# @example Creating a custom strategy
|
|
9
|
+
# class ErrorRateStrategy
|
|
10
|
+
# def check_compatibility(config)
|
|
11
|
+
# if config.window_size.nil?
|
|
12
|
+
# incompatible("`window_size` should be set")
|
|
13
|
+
# else
|
|
14
|
+
# compatible
|
|
15
|
+
# end
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# def stop_traffic?(config, metrics)
|
|
19
|
+
# total = metrics.successes + metrics.failures
|
|
20
|
+
# return false if total < 10 # Minimum sample size
|
|
21
|
+
#
|
|
22
|
+
# error_rate = metrics.failures.fdiv(total)
|
|
23
|
+
# error_rate >= 0.5 # Stop traffic when error rate reaches 50%
|
|
24
|
+
# end
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
interface _TrafficControl
|
|
28
|
+
# Checks if the strategy is compatible with the given Stoplight configuration.
|
|
29
|
+
def check_compatibility: (Config) -> CompatibilityResult
|
|
30
|
+
|
|
31
|
+
# Determines whether traffic should be stopped based on the Stoplight's
|
|
32
|
+
# current state and metrics.
|
|
33
|
+
# @return +true+ if traffic should be stopped otherwise false
|
|
34
|
+
def stop_traffic?: (Config, Domain::MetricsSnapshot) -> bool
|
|
35
|
+
|
|
36
|
+
# Object methods
|
|
37
|
+
def ==: (untyped) -> bool
|
|
38
|
+
def is_a?: (untyped) -> bool
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
type decision = :green | :yellow | :red
|
|
4
|
+
|
|
5
|
+
# Strategies for determining how to recover traffic flow through the Stoplight.
|
|
6
|
+
# These strategies evaluate recovery metrics to decide which color the Stoplight should
|
|
7
|
+
# transition to during the recovery process.
|
|
8
|
+
#
|
|
9
|
+
# @example Creating a custom traffic recovery strategy
|
|
10
|
+
# class GradualRecovery
|
|
11
|
+
# def initialize(min_success_rate: 0.8, min_samples: 100)
|
|
12
|
+
# @min_success_rate = min_success_rate
|
|
13
|
+
# @min_samples = min_samples
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# def determine_color(config, metrics)
|
|
17
|
+
# total_probes = metrics.recovery_probe_successes + metrics.recovery_probe_errors
|
|
18
|
+
#
|
|
19
|
+
# if total_probes < @min_samples
|
|
20
|
+
# return Color::YELLOW # Keep recovering, not enough samples
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# success_rate = metrics.recovery_probe_successes.fdiv(total_probes)
|
|
24
|
+
# if success_rate >= @min_success_rate
|
|
25
|
+
# Color::GREEN # Recovery successful
|
|
26
|
+
# elsif success_rate <= 0.2
|
|
27
|
+
# Color::RED # Recovery failed, too many errors
|
|
28
|
+
# else
|
|
29
|
+
# Color::YELLOW # Continue recovery
|
|
30
|
+
# end
|
|
31
|
+
# end
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
interface _TrafficRecovery
|
|
35
|
+
# Checks if the strategy is compatible with the given Stoplight configuration.
|
|
36
|
+
def check_compatibility: (Config) -> CompatibilityResult
|
|
37
|
+
|
|
38
|
+
# Determines the appropriate recovery state based on the Stoplight's
|
|
39
|
+
# current metrics and recovery progress.
|
|
40
|
+
def determine_color: (Config, Domain::MetricsSnapshot) -> decision
|
|
41
|
+
|
|
42
|
+
# Object methods
|
|
43
|
+
def ==: (untyped) -> bool
|
|
44
|
+
def is_a?: (untyped) -> bool
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
class StateSnapshot < Data
|
|
4
|
+
def breached_at: -> Time?
|
|
5
|
+
def locked_state: -> state
|
|
6
|
+
def recovery_scheduled_after: -> Time?
|
|
7
|
+
def recovery_scheduled_after!: -> Time
|
|
8
|
+
def recovery_started_at: -> Time?
|
|
9
|
+
def recovery_started_at!: -> Time
|
|
10
|
+
def time: -> Time
|
|
11
|
+
|
|
12
|
+
def self.new: (
|
|
13
|
+
breached_at: Time?,
|
|
14
|
+
locked_state: state,
|
|
15
|
+
recovery_scheduled_after: Time?,
|
|
16
|
+
recovery_started_at: Time?,
|
|
17
|
+
time: Time
|
|
18
|
+
) -> instance
|
|
19
|
+
|
|
20
|
+
def initialize: (
|
|
21
|
+
breached_at: Time?,
|
|
22
|
+
locked_state: state,
|
|
23
|
+
recovery_scheduled_after: Time?,
|
|
24
|
+
recovery_started_at: Time?,
|
|
25
|
+
time: Time
|
|
26
|
+
) -> void
|
|
27
|
+
|
|
28
|
+
def color: -> color
|
|
29
|
+
def recovery_started?: -> bool
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
module Strategies
|
|
4
|
+
class GreenRunStrategy
|
|
5
|
+
include _RunStrategy
|
|
6
|
+
|
|
7
|
+
attr_reader request_tracker: Tracker::Request
|
|
8
|
+
@error_tracking_policy: ErrorTrackingPolicy
|
|
9
|
+
|
|
10
|
+
def initialize: (error_tracking_policy: ErrorTrackingPolicy, request_tracker: Tracker::Request) -> void
|
|
11
|
+
|
|
12
|
+
def record_error: (StandardError) -> void
|
|
13
|
+
def record_success: -> void
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
module Strategies
|
|
4
|
+
class RedRunStrategy
|
|
5
|
+
include _RunStrategy
|
|
6
|
+
|
|
7
|
+
@name: String
|
|
8
|
+
@cool_off_time: duration
|
|
9
|
+
|
|
10
|
+
def initialize: (name: String, cool_off_time: duration) -> void
|
|
11
|
+
|
|
12
|
+
private def record_error: (StandardError) -> void
|
|
13
|
+
private def record_success: -> void
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
module Strategies
|
|
4
|
+
class YellowRunStrategy
|
|
5
|
+
include _RunStrategy
|
|
6
|
+
|
|
7
|
+
attr_reader state_store: Domain::_StateStore
|
|
8
|
+
attr_reader metrics_store: _MetricsStore
|
|
9
|
+
attr_reader recovery_lock_store: _RecoveryLockStore
|
|
10
|
+
attr_reader notifiers: Array[state_transition_notifier]
|
|
11
|
+
attr_reader request_tracker: Tracker::RecoveryProbe
|
|
12
|
+
attr_reader red_run_strategy: RedRunStrategy
|
|
13
|
+
|
|
14
|
+
@name: String
|
|
15
|
+
@config: Domain::Config
|
|
16
|
+
@error_tracking_policy: ErrorTrackingPolicy
|
|
17
|
+
|
|
18
|
+
def initialize: (
|
|
19
|
+
name: String,
|
|
20
|
+
error_tracking_policy: ErrorTrackingPolicy,
|
|
21
|
+
notifiers: Array[state_transition_notifier],
|
|
22
|
+
request_tracker: Tracker::RecoveryProbe,
|
|
23
|
+
red_run_strategy: RedRunStrategy,
|
|
24
|
+
state_store: Domain::_StateStore,
|
|
25
|
+
metrics_store: _MetricsStore,
|
|
26
|
+
recovery_lock_store: _RecoveryLockStore,
|
|
27
|
+
config: Domain::Config,
|
|
28
|
+
) -> void
|
|
29
|
+
|
|
30
|
+
def with_recovery_lock: [T] (
|
|
31
|
+
fallback: (^(StandardError?) -> T)?,
|
|
32
|
+
state_snapshot: StateSnapshot,
|
|
33
|
+
code: ^() -> T,
|
|
34
|
+
) { () -> T } -> T
|
|
35
|
+
|
|
36
|
+
def record_recovery_probe_success: () -> void
|
|
37
|
+
def record_recovery_probe_failure: (StandardError) -> void
|
|
38
|
+
def enter_recovery: (StateSnapshot) -> void
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
module Tracker
|
|
4
|
+
class RecoveryProbe < Base
|
|
5
|
+
attr_reader traffic_recovery: _TrafficRecovery
|
|
6
|
+
attr_reader notifiers: Array[state_transition_notifier]
|
|
7
|
+
attr_reader config: Config
|
|
8
|
+
attr_reader metrics_store: _MetricsStore
|
|
9
|
+
attr_reader state_store: _StateStore
|
|
10
|
+
|
|
11
|
+
def initialize: (
|
|
12
|
+
config: Config,
|
|
13
|
+
traffic_recovery: _TrafficRecovery,
|
|
14
|
+
notifiers: Array[state_transition_notifier],
|
|
15
|
+
metrics_store: _MetricsStore,
|
|
16
|
+
state_store: _StateStore,
|
|
17
|
+
) -> void
|
|
18
|
+
|
|
19
|
+
def record_failure: (StandardError exception) -> void
|
|
20
|
+
def record_success: -> void
|
|
21
|
+
def recover: -> void
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Domain
|
|
3
|
+
module Tracker
|
|
4
|
+
class Request < Base
|
|
5
|
+
attr_reader config: Config
|
|
6
|
+
attr_reader traffic_control: _TrafficControl
|
|
7
|
+
attr_reader notifiers: Array[state_transition_notifier]
|
|
8
|
+
attr_reader metrics_store: _MetricsStore
|
|
9
|
+
attr_reader state_store: _StateStore
|
|
10
|
+
|
|
11
|
+
def initialize: (
|
|
12
|
+
config: Config,
|
|
13
|
+
traffic_control: _TrafficControl,
|
|
14
|
+
notifiers: Array[state_transition_notifier],
|
|
15
|
+
metrics_store: _MetricsStore,
|
|
16
|
+
state_store: _StateStore,
|
|
17
|
+
) -> void
|
|
18
|
+
|
|
19
|
+
def record_failure: (StandardError exception) -> void
|
|
20
|
+
def record_success: -> void
|
|
21
|
+
|
|
22
|
+
private def transition_to_red: (StandardError exception, metrics: MetricsSnapshot) -> void
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Infrastructure
|
|
3
|
+
module FailSafe
|
|
4
|
+
class DataStore
|
|
5
|
+
include Domain::_DataStore
|
|
6
|
+
attr_reader data_store: Domain::_DataStore
|
|
7
|
+
attr_reader failover_data_store: Domain::_DataStore
|
|
8
|
+
attr_reader error_notifier: error_notifier
|
|
9
|
+
private attr_reader circuit_breaker: Domain::Light
|
|
10
|
+
|
|
11
|
+
def initialize: (
|
|
12
|
+
data_store: Domain::_DataStore,
|
|
13
|
+
error_notifier: error_notifier,
|
|
14
|
+
failover_data_store: Domain::_DataStore,
|
|
15
|
+
circuit_breaker: Domain::Light
|
|
16
|
+
) -> void
|
|
17
|
+
|
|
18
|
+
private def with_fallback: [T] (
|
|
19
|
+
String | Symbol method_name,
|
|
20
|
+
*untyped,
|
|
21
|
+
**untyped,
|
|
22
|
+
) { () -> T } -> T
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Stoplight
|
|
2
|
+
module Infrastructure
|
|
3
|
+
module FailSafe
|
|
4
|
+
module Storage
|
|
5
|
+
class Metrics
|
|
6
|
+
include Domain::_MetricsStore
|
|
7
|
+
|
|
8
|
+
attr_reader primary_store: Domain::_MetricsStore
|
|
9
|
+
attr_reader error_notifier: error_notifier
|
|
10
|
+
attr_reader failover_store: Domain::_MetricsStore
|
|
11
|
+
attr_reader circuit_breaker: Domain::Light
|
|
12
|
+
|
|
13
|
+
def initialize: (
|
|
14
|
+
primary_store: Domain::_MetricsStore,
|
|
15
|
+
error_notifier: error_notifier,
|
|
16
|
+
failover_store: Domain::_MetricsStore,
|
|
17
|
+
circuit_breaker: Domain::Light
|
|
18
|
+
) -> void
|
|
19
|
+
|
|
20
|
+
def fallback: [T] { () -> T } -> ^(StandardError?) -> T
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|