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 +4 -4
- data/README.md +5 -5
- data/UPGRADING.md +14 -0
- data/lib/stoplight/data_store.rb +7 -0
- data/lib/stoplight/error.rb +1 -1
- data/lib/stoplight/infrastructure/redis/storage/scripting.rb +9 -3
- data/lib/stoplight/version.rb +1 -1
- data/lib/stoplight/wiring/light_factory.rb +10 -1
- data/lib/stoplight.rb +0 -2
- data/sig/stoplight/data_store/redis.rbs +3 -0
- data/sig/stoplight/infrastructure/redis/storage/scripting.rbs +2 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e9e835f7351f236b8965d8179da39eff4eaf768bbf066c94cb35f8ed6f0360f6
|
|
4
|
+
data.tar.gz: ea64aa21f4874b40843e2f18716da346b4e0a4fbf77f57ca777bafa8e396ae5b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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:
|
|
84
|
-
light.color # =>
|
|
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 #=>
|
|
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/
|
|
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
|
data/lib/stoplight/data_store.rb
CHANGED
|
@@ -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
|
data/lib/stoplight/error.rb
CHANGED
|
@@ -18,7 +18,7 @@ module Stoplight
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
class RedLight < Base
|
|
21
|
-
EXCEPTION_MESSAGE =
|
|
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
|
-
|
|
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
|
|
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
|
|
data/lib/stoplight/version.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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.
|
|
348
|
+
rubygems_version: 4.0.20
|
|
349
349
|
specification_version: 4
|
|
350
350
|
summary: Traffic control for code.
|
|
351
351
|
test_files: []
|