stoplight 5.5.0 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/stoplight/admin/actions/remove.rb +23 -0
  4. data/lib/stoplight/admin/dependencies.rb +6 -1
  5. data/lib/stoplight/admin/helpers.rb +10 -5
  6. data/lib/stoplight/admin/lights_repository.rb +26 -14
  7. data/lib/stoplight/admin/views/_card.erb +13 -1
  8. data/lib/stoplight/admin.rb +9 -0
  9. data/lib/stoplight/common/deprecations.rb +11 -0
  10. data/lib/stoplight/domain/config.rb +5 -1
  11. data/lib/stoplight/domain/data_store.rb +58 -6
  12. data/lib/stoplight/domain/failure.rb +2 -0
  13. data/lib/stoplight/domain/light/configuration_builder_interface.rb +120 -16
  14. data/lib/stoplight/domain/light.rb +34 -24
  15. data/lib/stoplight/domain/metrics.rb +64 -0
  16. data/lib/stoplight/domain/recovery_lock_token.rb +15 -0
  17. data/lib/stoplight/domain/{metadata.rb → state_snapshot.rb} +29 -37
  18. data/lib/stoplight/domain/storage/metrics.rb +42 -0
  19. data/lib/stoplight/domain/storage/recovery_lock.rb +56 -0
  20. data/lib/stoplight/domain/storage/state.rb +87 -0
  21. data/lib/stoplight/domain/strategies/green_run_strategy.rb +2 -2
  22. data/lib/stoplight/domain/strategies/red_run_strategy.rb +3 -3
  23. data/lib/stoplight/domain/strategies/run_strategy.rb +2 -7
  24. data/lib/stoplight/domain/strategies/yellow_run_strategy.rb +63 -36
  25. data/lib/stoplight/domain/tracker/base.rb +0 -29
  26. data/lib/stoplight/domain/tracker/recovery_probe.rb +26 -22
  27. data/lib/stoplight/domain/tracker/request.rb +26 -21
  28. data/lib/stoplight/domain/traffic_control/base.rb +5 -5
  29. data/lib/stoplight/domain/traffic_control/consecutive_errors.rb +3 -7
  30. data/lib/stoplight/domain/traffic_control/error_rate.rb +3 -3
  31. data/lib/stoplight/domain/traffic_recovery/base.rb +5 -5
  32. data/lib/stoplight/domain/traffic_recovery/consecutive_successes.rb +4 -8
  33. data/lib/stoplight/domain/traffic_recovery.rb +0 -1
  34. data/lib/stoplight/infrastructure/data_store/fail_safe.rb +164 -0
  35. data/lib/stoplight/infrastructure/data_store/memory/metrics.rb +27 -0
  36. data/lib/stoplight/infrastructure/data_store/memory/recovery_lock_store.rb +54 -0
  37. data/lib/stoplight/infrastructure/data_store/memory/recovery_lock_token.rb +20 -0
  38. data/lib/stoplight/infrastructure/data_store/memory/state.rb +21 -0
  39. data/lib/stoplight/infrastructure/data_store/memory.rb +163 -132
  40. data/lib/stoplight/infrastructure/data_store/redis/lua_scripts/get_metrics.lua +26 -0
  41. data/lib/stoplight/infrastructure/data_store/redis/lua_scripts/record_recovery_probe_failure.lua +27 -0
  42. data/lib/stoplight/infrastructure/data_store/redis/lua_scripts/record_recovery_probe_success.lua +23 -0
  43. data/lib/stoplight/infrastructure/data_store/redis/lua_scripts/release_lock.lua +6 -0
  44. data/lib/stoplight/infrastructure/data_store/redis/recovery_lock_store.rb +73 -0
  45. data/lib/stoplight/infrastructure/data_store/redis/recovery_lock_token.rb +35 -0
  46. data/lib/stoplight/infrastructure/data_store/redis/scripting.rb +71 -0
  47. data/lib/stoplight/infrastructure/data_store/redis.rb +211 -165
  48. data/lib/stoplight/infrastructure/notifier/fail_safe.rb +62 -0
  49. data/lib/stoplight/infrastructure/storage/compatibility_metrics.rb +48 -0
  50. data/lib/stoplight/infrastructure/storage/compatibility_recovery_lock.rb +36 -0
  51. data/lib/stoplight/infrastructure/storage/compatibility_recovery_metrics.rb +55 -0
  52. data/lib/stoplight/infrastructure/storage/compatibility_state.rb +55 -0
  53. data/lib/stoplight/version.rb +1 -1
  54. data/lib/stoplight/wiring/data_store/base.rb +11 -0
  55. data/lib/stoplight/wiring/data_store/memory.rb +10 -0
  56. data/lib/stoplight/wiring/data_store/redis.rb +25 -0
  57. data/lib/stoplight/wiring/default.rb +1 -1
  58. data/lib/stoplight/wiring/default_configuration.rb +1 -1
  59. data/lib/stoplight/wiring/default_factory_builder.rb +1 -1
  60. data/lib/stoplight/wiring/light_builder.rb +185 -0
  61. data/lib/stoplight/wiring/light_factory/compatibility_validator.rb +55 -0
  62. data/lib/stoplight/wiring/light_factory/config_normalizer.rb +71 -0
  63. data/lib/stoplight/wiring/light_factory/configuration_pipeline.rb +72 -0
  64. data/lib/stoplight/wiring/light_factory/traffic_control_dsl.rb +26 -0
  65. data/lib/stoplight/wiring/light_factory/traffic_recovery_dsl.rb +21 -0
  66. data/lib/stoplight/wiring/light_factory.rb +45 -132
  67. data/lib/stoplight/wiring/notifier_factory.rb +26 -0
  68. data/lib/stoplight/wiring/public_api.rb +3 -2
  69. data/lib/stoplight.rb +18 -3
  70. metadata +55 -16
  71. data/lib/stoplight/infrastructure/data_store/redis/get_metadata.lua +0 -38
  72. data/lib/stoplight/infrastructure/data_store/redis/lua.rb +0 -25
  73. data/lib/stoplight/infrastructure/dependency_injection/container.rb +0 -249
  74. data/lib/stoplight/infrastructure/dependency_injection/unresolved_dependency_error.rb +0 -13
  75. data/lib/stoplight/wiring/container.rb +0 -80
  76. data/lib/stoplight/wiring/fail_safe_data_store.rb +0 -123
  77. data/lib/stoplight/wiring/fail_safe_notifier.rb +0 -79
  78. data/lib/stoplight/wiring/system_container.rb +0 -9
  79. data/lib/stoplight/wiring/system_light_factory.rb +0 -17
  80. /data/lib/stoplight/infrastructure/data_store/redis/{record_failure.lua → lua_scripts/record_failure.lua} +0 -0
  81. /data/lib/stoplight/infrastructure/data_store/redis/{record_success.lua → lua_scripts/record_success.lua} +0 -0
  82. /data/lib/stoplight/infrastructure/data_store/redis/{transition_to_green.lua → lua_scripts/transition_to_green.lua} +0 -0
  83. /data/lib/stoplight/infrastructure/data_store/redis/{transition_to_red.lua → lua_scripts/transition_to_red.lua} +0 -0
  84. /data/lib/stoplight/infrastructure/data_store/redis/{transition_to_yellow.lua → lua_scripts/transition_to_yellow.lua} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 297bbf636a9d6fa8e47b2241a3bfe0ccf357954044dc9cd02b79735012d92148
4
- data.tar.gz: 7e539fac482dbde352b0e971b20d29968758c85017c2f917859d5130ef8ed7a1
3
+ metadata.gz: d96e1b5dcce81c642d059b07b2e274b8c7dbd7f246b86ee25ce40567eaba8418
4
+ data.tar.gz: e6b04f0ff592f89f345ff3f9ec9e26b86463ff0baeb56ef752cbd00b7f8952b8
5
5
  SHA512:
6
- metadata.gz: 53277c7ec692204dc99c96dbf4d8e224d47424b6f5605445de2dc9122d09adedcb683ca783be7f0496db0b6e9aef9045636100da889055e0cb0ee4a4c398ab1e
7
- data.tar.gz: f0dd133ab0aa988a9bac5d9b2954299c5cf47ee86f08482b0199c8108fe953ae6e44c5f781457cda74063a93d1686da9ce76b4e4780ffb16d66dd70790b17815
6
+ metadata.gz: 01c5c2356f84eaeade94edba7113e700682911558d165b8b60186abbe0cda3d0f453427b8ab6e96f4ab51948e3ec5a109e53e1b51cc15c46c3fd79aad4865768
7
+ data.tar.gz: 94633b744ef88219f66289d9aae91bbb35b013bbea82c84f0f253abd15d4e5bd7ea5a123c39dffc36911479b1663cee71f786110be0ee15c3c8f56d035032e76
data/README.md CHANGED
@@ -534,7 +534,7 @@ class ApplicationController < ActionController::Base
534
534
 
535
535
  def stoplight(&block)
536
536
  Stoplight("#{params[:controller]}##{params[:action]}")
537
- .run(-> { render(nothing: true, status: :service_unavailable) }, &block)
537
+ .run(-> (*) { render(nothing: true, status: :service_unavailable) }, &block)
538
538
  end
539
539
  end
540
540
  ```
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stoplight
4
+ class Admin
5
+ module Actions
6
+ # This action removes a light's metadata from Redis
7
+ class Remove < Action
8
+ # @param params [Hash] query parameters
9
+ # @return [void]
10
+ def call(params)
11
+ light_names(params).each do |name|
12
+ lights_repository.remove(name)
13
+ end
14
+ end
15
+
16
+ private def light_names(params)
17
+ Array(params[:names])
18
+ .map { |name| CGI.unescape(name) }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -8,7 +8,7 @@ module Stoplight
8
8
  attr_reader :data_store
9
9
  private :data_store
10
10
 
11
- # @param data_store [Stoplight::DataStore::Base]
11
+ # @param data_store [Stoplight::Domain::DataStore]
12
12
  def initialize(data_store:)
13
13
  @data_store = data_store
14
14
  end
@@ -45,6 +45,11 @@ module Stoplight
45
45
  def green_all_action
46
46
  Stoplight::Admin::Actions::LockAllGreen.new(lights_repository: lights_repository)
47
47
  end
48
+
49
+ # @return [Stoplight::Admin::Actions::Remove]
50
+ def remove_action
51
+ Stoplight::Admin::Actions::Remove.new(lights_repository: lights_repository)
52
+ end
48
53
  end
49
54
  end
50
55
  end
@@ -15,11 +15,16 @@ module Stoplight
15
15
  end
16
16
 
17
17
  private def data_store
18
- settings.data_store.tap do |data_store|
19
- if data_store.is_a?(Stoplight::DataStore::Memory)
20
- raise "Stoplight Admin requires a persistent data store, but the current data store is Memory. " \
21
- "Please configure a different data store in your Stoplight configuration."
22
- end
18
+ if settings.data_store.is_a?(Stoplight::DataStore::Memory)
19
+ raise "Stoplight Admin requires a persistent data store, but the current data store is Memory. " \
20
+ "Please configure a different data store in your Stoplight configuration."
21
+ else
22
+ Stoplight::Wiring::LightBuilder.new(
23
+ {
24
+ data_store: settings.data_store,
25
+ config: Wiring::Light::DefaultConfig
26
+ }
27
+ ).__send__(:data_store)
23
28
  end
24
29
  end
25
30
  end
@@ -4,11 +4,11 @@ module Stoplight
4
4
  class Admin
5
5
  class LightsRepository
6
6
  # @!attribute data_store
7
- # @return [Stoplight::DataStore::Base]
7
+ # @return [Stoplight::Domain::DataStore]
8
8
  attr_reader :data_store
9
9
  private :data_store
10
10
 
11
- # @param data_store [Stoplight::DataStore::Base]
11
+ # @param data_store [Stoplight::Domain::DataStore]
12
12
  def initialize(data_store:)
13
13
  @data_store = data_store
14
14
  end
@@ -37,37 +37,49 @@ module Stoplight
37
37
  # color
38
38
  # @return [void]
39
39
  def lock(name, color = nil)
40
- light = build_light(name)
40
+ config = build_config(name)
41
+ color ||= data_store.get_state_snapshot(config).color
41
42
 
42
- case color || light.color
43
+ case color
43
44
  when Stoplight::Color::GREEN
44
- light.lock(Stoplight::Color::GREEN)
45
+ data_store.set_state(config, Stoplight::State::LOCKED_GREEN)
45
46
  else
46
- light.lock(Stoplight::Color::RED)
47
+ data_store.set_state(config, Stoplight::State::LOCKED_RED)
47
48
  end
48
49
  end
49
50
 
50
51
  # @param name [String] unlocks light by its name
51
52
  # @return [void]
52
53
  def unlock(name)
53
- build_light(name).unlock
54
+ config = build_config(name)
55
+ data_store.set_state(config, Domain::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)
54
64
  end
55
65
 
56
66
  private def load_light(name)
57
- light = build_light(name)
67
+ config = build_config(name)
68
+
58
69
  # failures, state
59
- metadata = data_store.get_metadata(light.config)
70
+ state_snapshot = data_store.get_state_snapshot(config)
71
+ metrics = data_store.get_metrics(config)
60
72
 
61
73
  Light.new(
62
74
  name: name,
63
- color: light.color,
64
- state: metadata.locked_state,
65
- failures: [metadata.last_error].compact
75
+ color: state_snapshot.color,
76
+ state: state_snapshot.locked_state,
77
+ failures: [metrics.last_error].compact
66
78
  )
67
79
  end
68
80
 
69
- private def build_light(name)
70
- Stoplight(name, data_store: data_store)
81
+ private def build_config(name)
82
+ Wiring::Light::DefaultConfig.with(name:)
71
83
  end
72
84
  end
73
85
  end
@@ -1,6 +1,6 @@
1
1
  <div class="max-w-xl mr-5 p-6 border border-gray-200 rounded-lg shadow-sm dark:bg-gray-800 dark:border-gray-700">
2
2
  <div class="flex items-center">
3
- <% light_name = ERB::Util.html_escape(light.name) %>
3
+ <% light_name = CGI.escape(light.name) %>
4
4
 
5
5
  <div class="relative">
6
6
  <div class="relative inline-flex items-center justify-center w-10 h-10 overflow-hidden bg-<%= color %>-100 rounded-full dark:bg-<%= color %>-600">
@@ -83,6 +83,18 @@
83
83
  Lock Green
84
84
  </a>
85
85
  </li>
86
+ <li>
87
+ <a href="<%= url("/remove?names=#{light_name}") %>" data-turbo-method="post" data-turbo-confirm="Are you sure you want to remove this light?" class="flex items-center py-2 px-4 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">
88
+ <svg class="flex w-4 h-4 me-1.5 text-red-600 shrink-0" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
89
+ <polyline points="3 6 5 6 21 6"/>
90
+ <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/>
91
+ <path d="M10 11v6"/>
92
+ <path d="M14 11v6"/>
93
+ <path d="M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2"/>
94
+ </svg>
95
+ Remove
96
+ </a>
97
+ </li>
86
98
  </ul>
87
99
  </div>
88
100
  </div>
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "cgi/escape"
4
+ require "cgi/util" if RUBY_VERSION < "3.5"
5
+
3
6
  begin
4
7
  require "sinatra/base"
5
8
  require "sinatra/json"
@@ -63,5 +66,11 @@ module Stoplight
63
66
 
64
67
  redirect to("/")
65
68
  end
69
+
70
+ post "/remove" do
71
+ dependencies.remove_action.call(params)
72
+
73
+ redirect to("/")
74
+ end
66
75
  end
67
76
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stoplight
4
+ module Common
5
+ module Deprecations
6
+ extend self
7
+
8
+ def deprecate(message) = warn("[DEPRECATION] #{message}")
9
+ end
10
+ end
11
+ end
@@ -7,7 +7,7 @@ module Stoplight
7
7
  # # @!attribute [r] name
8
8
  # @return [String]
9
9
  #
10
- # @!attribute [r] cool_off_time
10
+ # @!attribute [r] cool_off_time - cool-off time in seconds
11
11
  # @return [Numeric]
12
12
  #
13
13
  # @!attribute [r] threshold
@@ -50,6 +50,10 @@ module Stoplight
50
50
 
51
51
  !skip && track
52
52
  end
53
+
54
+ def cool_off_time_in_milliseconds
55
+ cool_off_time * 1_000
56
+ end
53
57
  end
54
58
  end
55
59
  end
@@ -14,11 +14,41 @@ module Stoplight
14
14
  raise NotImplementedError
15
15
  end
16
16
 
17
- # Retrieves metadata for a specific light configuration.
17
+ # Retrieves metrics for a specific light configuration.
18
+ #
19
+ # @param config [Stoplight::Domain::Config]
20
+ # @return [Stoplight::Domain::Metrics]
21
+ def get_metrics(config)
22
+ raise NotImplementedError
23
+ end
24
+
25
+ # Retrieves recovery metrics for a specific light configuration.
26
+ #
27
+ # @param config [Stoplight::Domain::Config]
28
+ # @return [Stoplight::Domain::Metrics]
29
+ def get_recovery_metrics(config)
30
+ raise NotImplementedError
31
+ end
32
+
33
+ # Retrieves State Snapshot for a specific light configuration.
18
34
  #
19
35
  # @param config [Stoplight::Domain::Config] The light configuration.
20
- # @return [Stoplight::Domain::Metadata] The metadata associated with the light.
21
- def get_metadata(config)
36
+ # @return [Stoplight::Domain::StateSnapshot]
37
+ def get_state_snapshot(config)
38
+ raise NotImplementedError
39
+ end
40
+
41
+ # Clears windowed metrics (successes/errors) to prevent
42
+ # stale failures from before recovery from affecting post-recovery decisions.
43
+ # Consecutive counts are intentionally preserved as they track current streaks.
44
+ #
45
+ # @param config [Stoplight::Domain::Config] The light configuration.
46
+ # @return [void]
47
+ def clear_metrics(config)
48
+ raise NotImplementedError
49
+ end
50
+
51
+ def clear_recovery_metrics(config)
22
52
  raise NotImplementedError
23
53
  end
24
54
 
@@ -26,7 +56,7 @@ module Stoplight
26
56
  #
27
57
  # @param config [Stoplight::Domain::Config]
28
58
  # @param exception [Exception]
29
- # @return [Stoplight::Domain::Metadata] The metadata associated with the light.
59
+ # @return [void]
30
60
  def record_failure(config, exception)
31
61
  raise NotImplementedError
32
62
  end
@@ -43,7 +73,7 @@ module Stoplight
43
73
  #
44
74
  # @param config [Stoplight::Domain::Config]
45
75
  # @param failure [Failure]
46
- # @return [Stoplight::Domain::Metadata]
76
+ # @return [void]
47
77
  def record_recovery_probe_failure(config, failure)
48
78
  raise NotImplementedError
49
79
  end
@@ -51,7 +81,7 @@ module Stoplight
51
81
  # Records a successful recovery probe for a specific light configuration.
52
82
  #
53
83
  # @param config [Stoplight::Domain::Config]
54
- # @return [Stoplight::Domain::Metadata]
84
+ # @return [void]
55
85
  def record_recovery_probe_success(config)
56
86
  raise NotImplementedError
57
87
  end
@@ -65,6 +95,18 @@ module Stoplight
65
95
  raise NotImplementedError
66
96
  end
67
97
 
98
+ # Acquires recovery lock for serializing probe execution.
99
+ #
100
+ # @param config [Stoplight::Domain::Config]
101
+ # @return [Stoplight::Domain::LockToken, nil] Lock if acquired, nil if contended
102
+ def acquire_recovery_lock(config) = raise NotImplementedError
103
+
104
+ # Releases previously acquired lock.
105
+ #
106
+ # @param lock [Stoplight::Domain::RecoveryLockToken]
107
+ # @return [void]
108
+ def release_recovery_lock(lock) = raise NotImplementedError
109
+
68
110
  # Transitions the Stoplight to the specified color.
69
111
  #
70
112
  # This method performs a color transition operation that works across distributed instances
@@ -88,6 +130,16 @@ module Stoplight
88
130
  def transition_to_color(config, color)
89
131
  raise NotImplementedError
90
132
  end
133
+
134
+ # Deletes metadata (and related persistent state) for the given light.
135
+ #
136
+ # Implementations may choose to only remove metadata; metrics may expire via TTL.
137
+ #
138
+ # @param config [Stoplight::Domain::Config]
139
+ # @return [void]
140
+ def delete_light(config)
141
+ raise NotImplementedError
142
+ end
91
143
  end
92
144
  # :nocov:
93
145
  end
@@ -29,6 +29,8 @@ module Stoplight
29
29
  @time = time
30
30
  end
31
31
 
32
+ alias_method :occurred_at, :time
33
+
32
34
  # @param other [Failure]
33
35
  # @return [Boolean]
34
36
  def ==(other)
@@ -15,9 +15,22 @@ module Stoplight
15
15
  #
16
16
  # @param data_store [DataStore::Base]
17
17
  # @return [Stoplight::Light]
18
- # @deprecated consider using +Light#with+ for reconfiguration
18
+ # @deprecated
19
19
  def with_data_store(data_store)
20
- with(data_store:)
20
+ deprecate(<<~MSG)
21
+ Light#with_data_store is deprecated and will be removed in v6.0.0.
22
+
23
+ Circuit breakers should be configured once at creation, not cloned with
24
+ modifications.
25
+
26
+ Instead of:
27
+ light = Stoplight('api-call')
28
+ modified = light.with_data_store(data_stare)
29
+
30
+ Configure correctly from the start:
31
+ Stoplight('api-call', data_store:)
32
+ MSG
33
+ with_without_warning(data_store:)
21
34
  end
22
35
 
23
36
  # Configures cool off time. Stoplight automatically tries to recover
@@ -29,9 +42,22 @@ module Stoplight
29
42
  #
30
43
  # @param cool_off_time [Numeric] number of seconds
31
44
  # @return [Stoplight::Light]
32
- # @deprecated consider using +Light#with+ for reconfiguration
45
+ # @deprecated
33
46
  def with_cool_off_time(cool_off_time)
34
- with(cool_off_time:)
47
+ deprecate(<<~MSG)
48
+ Light#with_cool_off_time is deprecated and will be removed in v6.0.0.
49
+
50
+ Circuit breakers should be configured once at creation, not cloned with
51
+ modifications.
52
+
53
+ Instead of:
54
+ light = Stoplight('api-call')
55
+ modified = light.with_cool_off_time(cool_off_time)
56
+
57
+ Configure correctly from the start:
58
+ Stoplight('api-call', cool_off_time:)
59
+ MSG
60
+ with_without_warning(cool_off_time:)
35
61
  end
36
62
 
37
63
  # Configures custom threshold. After this number of failures Stoplight
@@ -43,9 +69,22 @@ module Stoplight
43
69
  #
44
70
  # @param threshold [Numeric]
45
71
  # @return [Stoplight::Light]
46
- # @deprecated consider using +Light#with+ for reconfiguration
72
+ # @deprecated
47
73
  def with_threshold(threshold)
48
- with(threshold:)
74
+ deprecate(<<~MSG)
75
+ Light#with_threshold is deprecated and will be removed in v6.0.0.
76
+
77
+ Circuit breakers should be configured once at creation, not cloned with
78
+ modifications.
79
+
80
+ Instead of:
81
+ light = Stoplight('api-call')
82
+ modified = light.with_threshold(threshold)
83
+
84
+ Configure correctly from the start:
85
+ Stoplight('api-call', threshold:)
86
+ MSG
87
+ with_without_warning(threshold:)
49
88
  end
50
89
 
51
90
  # Configures custom window size which Stoplight uses to count failures. For example,
@@ -60,9 +99,22 @@ module Stoplight
60
99
  #
61
100
  # @param window_size [Numeric] number of seconds
62
101
  # @return [Stoplight::Light]
63
- # @deprecated consider using +Light#with+ for reconfiguration
102
+ # @deprecated
64
103
  def with_window_size(window_size)
65
- with(window_size:)
104
+ deprecate(<<~MSG)
105
+ Light#with_window_size is deprecated and will be removed in v6.0.0.
106
+
107
+ Circuit breakers should be configured once at creation, not cloned with
108
+ modifications.
109
+
110
+ Instead of:
111
+ light = Stoplight('api-call')
112
+ modified = light.with_window_size(window_size)
113
+
114
+ Configure correctly from the start:
115
+ Stoplight('api-call', window_size:)
116
+ MSG
117
+ with_without_warning(window_size:)
66
118
  end
67
119
 
68
120
  # Configures custom notifier
@@ -75,17 +127,43 @@ module Stoplight
75
127
  #
76
128
  # @param notifiers [Array<Notifier::Base>]
77
129
  # @return [Stoplight::Light]
78
- # @deprecated consider using +Light#with+ for reconfiguration
130
+ # @deprecated
79
131
  def with_notifiers(notifiers)
80
- with(notifiers:)
132
+ deprecate(<<~MSG)
133
+ Light#with_notifiers is deprecated and will be removed in v6.0.0.
134
+
135
+ Circuit breakers should be configured once at creation, not cloned with
136
+ modifications.
137
+
138
+ Instead of:
139
+ light = Stoplight('api-call')
140
+ modified = light.with_notifiers(notifiers)
141
+
142
+ Configure correctly from the start:
143
+ Stoplight('api-call', notifiers:)
144
+ MSG
145
+ with_without_warning(notifiers:)
81
146
  end
82
147
 
83
148
  # @param error_notifier [Proc]
84
149
  # @return [Stoplight::Light]
85
150
  # @api private
86
- # @deprecated consider using +Light#with+ for reconfiguration
151
+ # @deprecated
87
152
  def with_error_notifier(&error_notifier)
88
- with(error_notifier: error_notifier)
153
+ deprecate(<<~MSG)
154
+ Light#with_error_notifier is deprecated and will be removed in v6.0.0.
155
+
156
+ Circuit breakers should be configured once at creation, not cloned with
157
+ modifications.
158
+
159
+ Instead of:
160
+ light = Stoplight('api-call')
161
+ modified = light.with_error_notifier { |error| warn error }
162
+
163
+ Configure correctly from the start:
164
+ Stoplight('api-call', error_notifier: ->(error) { warn error })
165
+ MSG
166
+ with_without_warning(error_notifier: error_notifier)
89
167
  end
90
168
 
91
169
  # Configures a custom list of tracked errors that counts toward the threshold.
@@ -101,9 +179,22 @@ module Stoplight
101
179
  #
102
180
  # @param tracked_errors [Array<StandardError>]
103
181
  # @return [Stoplight::Light]
104
- # @deprecated consider using +Light#with+ for reconfiguration
182
+ # @deprecated
105
183
  def with_tracked_errors(*tracked_errors)
106
- with(tracked_errors:)
184
+ deprecate(<<~MSG)
185
+ Light#with_tracked_errors is deprecated and will be removed in v6.0.0.
186
+
187
+ Circuit breakers should be configured once at creation, not cloned with
188
+ modifications.
189
+
190
+ Instead of:
191
+ light = Stoplight('api-call')
192
+ modified = light.with_tracked_errors(TimeoutError, NetworkError)
193
+
194
+ Configure correctly from the start:
195
+ Stoplight('api-call', tracked_errors: [TimeoutError, NetworkError])
196
+ MSG
197
+ with_without_warning(tracked_errors:)
107
198
  end
108
199
 
109
200
  # Configures a custom list of skipped errors that do not count toward the threshold.
@@ -120,9 +211,22 @@ module Stoplight
120
211
  #
121
212
  # @param skipped_errors [Array<Exception>]
122
213
  # @return [Stoplight::Light]
123
- # @deprecated consider using +Light#with+ for reconfiguration
214
+ # @deprecated
124
215
  def with_skipped_errors(*skipped_errors)
125
- with(skipped_errors:)
216
+ deprecate(<<~MSG)
217
+ Light#with_skipped_errors is deprecated and will be removed in v6.0.0.
218
+
219
+ Circuit breakers should be configured once at creation, not cloned with
220
+ modifications.
221
+
222
+ Instead of:
223
+ light = Stoplight('api-call')
224
+ modified = light.with_skipped_errors(ActiveRecord::RecordNotFound)
225
+
226
+ Configure correctly from the start:
227
+ Stoplight('api-call', skipped_errors: [ActiveRecord::RecordNotFound])
228
+ MSG
229
+ with_without_warning(skipped_errors:)
126
230
  end
127
231
  end
128
232
  end