stoplight 6.0.0.rc5 → 6.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ade3c17bdafebab88e87b0f967dcf71a3fef99bb486c10a328e5110c4a4f456a
4
- data.tar.gz: 2dff3cb5d7731a337c8d558c73d7a3091b7bf1bafb060ae7d8bd74d570f2b4c2
3
+ metadata.gz: e9e835f7351f236b8965d8179da39eff4eaf768bbf066c94cb35f8ed6f0360f6
4
+ data.tar.gz: ea64aa21f4874b40843e2f18716da346b4e0a4fbf77f57ca777bafa8e396ae5b
5
5
  SHA512:
6
- metadata.gz: bd236321933ab75c09c468c3a12fddefe3002ce16cbfc7c6a28580d56fb3b6cace531792e9e5c0cae393158f5ba0ce6d62ec1425363bf4ba83abd8b6d4cb04ee
7
- data.tar.gz: ce3c272066f30882c34921144dbe48773fd6ed4812d6933ea96842a0848830c4e9e5b1f23b46d7d93556c87d56cb6b7345553c06135ab54f2111f21a52aac759
6
+ metadata.gz: 3bfa3fb97ed1f8f2743930257fefb4eba4f380b9b7eea122af9ca792206b43c27b42fb35292d95ab6c608ad70e3f99f6cf3ca0eb319e2d31c2010943e50a9730
7
+ data.tar.gz: 330fce49dcde86b0d0a9864143523db53caa20f64105cd40f85fcc4930769e3cd35ddb1f199aefce184b6c08eed69259acf0d697a9c4dc4e8245f482fc4a2474
data/README.md CHANGED
@@ -80,8 +80,8 @@ After the last failure, the light turns red. The next call will raise a `Stoplig
80
80
  executing the block:
81
81
 
82
82
  ```ruby
83
- light.run { 1 / 0 } #=> raises Stoplight::Error::RedLight: example-zero
84
- light.color # => "red"
83
+ light.run { 1 / 0 } #=> raises Stoplight::Error::RedLight: Light `Example` is red - traffic stopped until recovery.
84
+ light.color # => :red
85
85
  ```
86
86
 
87
87
  The `Stoplight::Error::RedLight` provides metadata about the error:
@@ -108,7 +108,7 @@ light.run { 1 / 1 } #=> 1
108
108
  If the test probe succeeds, the light turns green again. If it fails, the light turns red again.
109
109
 
110
110
  ```ruby
111
- light.color #=> "green"
111
+ light.color #=> :green
112
112
  ```
113
113
 
114
114
  ### Using Fallbacks
@@ -388,7 +388,7 @@ By default, Stoplight uses an in-memory data store:
388
388
 
389
389
  ```ruby
390
390
  require "stoplight"
391
- Stoplight::Default::DATA_STORE
391
+ Stoplight::Wiring::Default::DATA_STORE
392
392
  # => #<Stoplight::DataStore::Memory:...>
393
393
  ```
394
394
 
@@ -700,7 +700,7 @@ Fowler’s [CircuitBreaker][] article.
700
700
  [stoplight-sentry]: https://github.com/bolshakov/stoplight-sentry
701
701
  [stoplight-honeybadger]: https://github.com/qoqa/stoplight-honeybadger
702
702
  [stoplight-statsd]: https://github.com/bolshakov/stoplight-statsd
703
- [notifier interface documentation]: https://github.com/bolshakov/stoplight/blob/main/lib/stoplight/domain/state_transition_notifier.rb
703
+ [notifier interface documentation]: https://github.com/bolshakov/stoplight/blob/main/sig/stoplight/domain/ports/state_transition_notifier.rbs
704
704
  [camdez]: https://github.com/camdez
705
705
  [tfausak]: https://github.com/tfausak
706
706
  [bolshakov]: https://github.com/bolshakov
data/UPGRADING.md CHANGED
@@ -17,6 +17,7 @@ Here's what you'll want to tackle during your upgrade, roughly ordered from the
17
17
  - [ ] Round any fractional `cool_off_time` up to a whole number of seconds, at least 1
18
18
  - [ ] Drop `warn_on_clock_skew` from your Redis data store setup
19
19
  - [ ] Compare `light.color` and `light.state` against symbols, not strings, and pass a symbol to `light.lock`
20
+ - [ ] Check anything that parses or matches `Stoplight::Error::RedLight` messages - the message format changed
20
21
  - [ ] Test thoroughly in a staging environment
21
22
 
22
23
  ### Lights Are Registered and Reused
@@ -284,6 +285,19 @@ light.lock(Stoplight::Color::GREEN)
284
285
  Symbols are the idiomatic Ruby choice for a closed set of values. Anything that serializes them - logs, metrics tags,
285
286
  the Admin dashboard's JSON - renders the same text as before.
286
287
 
288
+ ### The `RedLight` Exception Message Changed
289
+
290
+ The message of `Stoplight::Error::RedLight` used to be the bare light name. It is now a sentence that names the light
291
+ and says what happened, so a log line or an error tracker (e.g., in Sentry) entry is readable on its own:
292
+
293
+ ```
294
+ # 5.x
295
+ Stoplight::Error::RedLight: Payment Service
296
+
297
+ # 6.0
298
+ Stoplight::Error::RedLight: Light `Payment Service` is red - traffic stopped until recovery.
299
+ ```
300
+
287
301
  ### Getting Help
288
302
 
289
303
  If you run into anything this guide doesn't cover, post to our [Discussions forum]. The configuration errors in 6.0
@@ -30,6 +30,13 @@ module Stoplight
30
30
  # @see Stoplight::Infrastructure::Redis::Key
31
31
  def self.key_space = KEY_SPACE
32
32
  def key_space = self.class.key_space
33
+
34
+ # Lua scripts are loaded into Redis once per server, so every light shares a single script cache.
35
+ #
36
+ # @api private
37
+ def __stoplight__scripting
38
+ @scripting ||= Infrastructure::Redis::Storage::Scripting.new(redis:)
39
+ end
33
40
  end
34
41
 
35
42
  class Memory < Base
@@ -18,7 +18,7 @@ module Stoplight
18
18
  end
19
19
 
20
20
  class RedLight < Base
21
- EXCEPTION_MESSAGE = 'Stoplight "%{light_name}" is red - traffic stopped until recovery.'
21
+ EXCEPTION_MESSAGE = "Light `%{light_name}` is red - traffic stopped until recovery."
22
22
  private_constant :EXCEPTION_MESSAGE
23
23
 
24
24
  # @!attribute light_name
@@ -21,6 +21,7 @@ module Stoplight
21
21
  @shas = Hash.new do |hash, script_name|
22
22
  hash[script_name] = Digest::SHA1.hexdigest(resolve_source(script_name))
23
23
  end
24
+ @invoked = Set.new
24
25
  end
25
26
 
26
27
  def call(script_name, keys: [], args: [])
@@ -33,18 +34,23 @@ module Stoplight
33
34
  rescue ::Redis::CommandError => error
34
35
  if error.message.include?("NOSCRIPT") && !retried
35
36
  retried = true
36
- reload_script(script_name)
37
+ if @invoked.include?(script_name) # skip warning for the first script invocation on app boot
38
+ warn "Stoplight is unable to find the script '#{script_name}' from Redis's script cache. " \
39
+ "Reloading and retrying..."
40
+ end
41
+ load_script(script_name)
37
42
  retry
38
43
  else
39
44
  raise error
40
45
  end
46
+ ensure
47
+ @invoked << script_name
41
48
  end
42
49
  end
43
50
 
44
51
  private
45
52
 
46
- def reload_script(script_name)
47
- warn "Stoplight is unable to find the script '#{script_name}' in Redis's script cache. Reloading and retrying..."
53
+ def load_script(script_name)
48
54
  @redis.then { |client| client.script(:load, resolve_source(script_name)) }
49
55
  end
50
56
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
- VERSION = Gem::Version.new("6.0.0.rc5")
4
+ VERSION = Gem::Version.new("6.0.0")
5
5
  end
@@ -72,7 +72,16 @@ module Stoplight
72
72
  attr_reader :system_name
73
73
 
74
74
  def recovery_lock_store = storage_set.recovery_lock_store
75
- def storage_scripting = Infrastructure::Redis::Storage::Scripting.new(redis:)
75
+
76
+ def storage_scripting
77
+ case data_store_config
78
+ when DataStore::Redis
79
+ data_store_config.__stoplight__scripting
80
+ else
81
+ raise T.absurd(data_store_config)
82
+ end
83
+ end
84
+
76
85
  def failover_system = T.must(@failover_system)
77
86
 
78
87
  def key_space
data/lib/stoplight.rb CHANGED
@@ -3,7 +3,6 @@
3
3
  require "concurrent/map"
4
4
  require "zeitwerk"
5
5
 
6
- # steep:ignore:start
7
6
  loader = Zeitwerk::Loader.for_gem
8
7
  loader.inflector.inflect("io" => "IO")
9
8
  loader.do_not_eager_load(
@@ -14,7 +13,6 @@ loader.do_not_eager_load(
14
13
  loader.ignore("#{__dir__}/generators")
15
14
  loader.ignore("#{__dir__}/stoplight/rspec.rb", "#{__dir__}/stoplight/rspec")
16
15
  loader.setup
17
- # steep:ignore:end
18
16
 
19
17
  module Stoplight # rubocop:disable Style/Documentation
20
18
  T = Types
@@ -7,9 +7,12 @@ module Stoplight
7
7
  KEY_SPACE: Infrastructure::Redis::Key
8
8
 
9
9
  attr_reader redis: Infrastructure::redis
10
+ @scripting: Infrastructure::Redis::Storage::Scripting?
10
11
 
11
12
  def initialize: (Infrastructure::redis) -> void
12
13
 
14
+ def __stoplight__scripting: -> Infrastructure::Redis::Storage::Scripting
15
+
13
16
  def self.key_space: -> Infrastructure::Redis::Key
14
17
  def key_space: -> Infrastructure::Redis::Key
15
18
  end
@@ -11,6 +11,7 @@ module Stoplight
11
11
 
12
12
  @scripts_path: Array[String]
13
13
  @shas: Hash[String, String]
14
+ @invoked: Set[String]
14
15
  @redis: redis
15
16
 
16
17
  def initialize: (
@@ -24,7 +25,7 @@ module Stoplight
24
25
  ?args: Array[_ToS]
25
26
  ) -> untyped
26
27
 
27
- private def reload_script: (String script_name) -> void
28
+ private def load_script: (String script_name) -> void
28
29
 
29
30
  private def resolve_source: (String script_name) -> String
30
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stoplight
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.rc5
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tëma Bolshakov
@@ -345,7 +345,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
345
345
  - !ruby/object:Gem::Version
346
346
  version: '0'
347
347
  requirements: []
348
- rubygems_version: 4.0.16
348
+ rubygems_version: 4.0.20
349
349
  specification_version: 4
350
350
  summary: Traffic control for code.
351
351
  test_files: []