stoplight 6.0.0.rc2 → 6.0.0.rc5
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 +3 -3
- data/UPGRADING.md +35 -0
- data/lib/stoplight/admin/helpers.rb +4 -0
- data/lib/stoplight/admin/views/_card.erb +3 -3
- data/lib/stoplight/admin.rb +2 -2
- data/lib/stoplight/color.rb +3 -3
- data/lib/stoplight/domain/state_snapshot.rb +1 -1
- data/lib/stoplight/infrastructure/redis/storage/state/state_snapshot.lua +9 -0
- data/lib/stoplight/infrastructure/redis/storage/state/transition_to_red.lua +2 -1
- data/lib/stoplight/infrastructure/redis/storage/state.rb +9 -9
- data/lib/stoplight/infrastructure/redis/storage/window_metrics/_evict.lua +4 -3
- data/lib/stoplight/state.rb +3 -3
- data/lib/stoplight/version.rb +1 -1
- data/lib/stoplight/wiring/system.rb +20 -7
- data/sig/stoplight/admin/actions/action.rbs +1 -1
- data/sig/stoplight/admin/helpers.rbs +3 -0
- data/sig/stoplight/domain/types.rbs +6 -6
- data/sig/stoplight/infrastructure/redis/storage/state.rbs +2 -2
- data/sig/stoplight/wiring/system.rbs +22 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ade3c17bdafebab88e87b0f967dcf71a3fef99bb486c10a328e5110c4a4f456a
|
|
4
|
+
data.tar.gz: 2dff3cb5d7731a337c8d558c73d7a3091b7bf1bafb060ae7d8bd74d570f2b4c2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd236321933ab75c09c468c3a12fddefe3002ce16cbfc7c6a28580d56fb3b6cace531792e9e5c0cae393158f5ba0ce6d62ec1425363bf4ba83abd8b6d4cb04ee
|
|
7
|
+
data.tar.gz: ce3c272066f30882c34921144dbe48773fd6ed4812d6933ea96842a0848830c4e9e5b1f23b46d7d93556c87d56cb6b7345553c06135ab54f2111f21a52aac759
|
data/README.md
CHANGED
|
@@ -678,8 +678,8 @@ Example: "Ruby 3.3 reaches end-of-life in March 2027, so Stoplight 7.0 will requ
|
|
|
678
678
|
## Development
|
|
679
679
|
|
|
680
680
|
After checking out the repo, run `bundle install` to install dependencies. Run tests with `bundle exec rspec` and check
|
|
681
|
-
code style with `bundle exec standardrb`.
|
|
682
|
-
|
|
681
|
+
code style with `bundle exec standardrb`. All work happens on `main` - see [CONTRIBUTING.md] for branch naming,
|
|
682
|
+
releases, and the contribution workflow.
|
|
683
683
|
|
|
684
684
|
## Credits
|
|
685
685
|
|
|
@@ -708,7 +708,7 @@ Fowler’s [CircuitBreaker][] article.
|
|
|
708
708
|
[complete list of contributors]: https://github.com/bolshakov/stoplight/graphs/contributors
|
|
709
709
|
[CircuitBreaker]: http://martinfowler.com/bliki/CircuitBreaker.html
|
|
710
710
|
[Redis]: https://redis.io/
|
|
711
|
-
[
|
|
711
|
+
[CONTRIBUTING.md]: CONTRIBUTING.md
|
|
712
712
|
[Valkey]: https://valkey.io/
|
|
713
713
|
[Ruby Maintenance Branches]: https://www.ruby-lang.org/en/downloads/branches/
|
|
714
714
|
[Redis's support policy]: https://redis.io/about/releases/
|
data/UPGRADING.md
CHANGED
|
@@ -8,6 +8,7 @@ Here's what you'll want to tackle during your upgrade, roughly ordered from the
|
|
|
8
8
|
|
|
9
9
|
- [ ] Make every `Stoplight("name", ...)` call site for the same name pass identical settings
|
|
10
10
|
- [ ] Move `data_store`, `notifiers`, and `error_notifier` from individual lights to `Stoplight.configure`
|
|
11
|
+
- [ ] Make sure that you run at least Ruby 3.3+, Redis 7.4+ (or Valkey 7.2+)
|
|
11
12
|
- [ ] Replace the `with_*` builder methods with settings passed at creation time
|
|
12
13
|
- [ ] Replace proc and anonymous-class error matchers with named classes or modules
|
|
13
14
|
- [ ] Account for Stoplight state reset after deployment
|
|
@@ -15,6 +16,7 @@ Here's what you'll want to tackle during your upgrade, roughly ordered from the
|
|
|
15
16
|
- [ ] Round any fractional `window_size` up to a whole number of seconds
|
|
16
17
|
- [ ] Round any fractional `cool_off_time` up to a whole number of seconds, at least 1
|
|
17
18
|
- [ ] Drop `warn_on_clock_skew` from your Redis data store setup
|
|
19
|
+
- [ ] Compare `light.color` and `light.state` against symbols, not strings, and pass a symbol to `light.lock`
|
|
18
20
|
- [ ] Test thoroughly in a staging environment
|
|
19
21
|
|
|
20
22
|
### Lights Are Registered and Reused
|
|
@@ -86,6 +88,13 @@ end
|
|
|
86
88
|
If you genuinely need more than one data store - separate Redis instances per tenant, for example - use named
|
|
87
89
|
systems, which own their own infrastructure. See [Systems: Namespace Isolation & Configuration][systems] for setup.
|
|
88
90
|
|
|
91
|
+
### Ruby 3.3 and Redis 7.4 Are the new Minimum
|
|
92
|
+
|
|
93
|
+
Stoplight 6 requires Ruby 3.3 or newer.
|
|
94
|
+
We also require Redis 7.4 or newer and Valkey 7.2 or newer and no longer tested or supported earlier versions.
|
|
95
|
+
|
|
96
|
+
See the [maintenance policy] for the versions under test.
|
|
97
|
+
|
|
89
98
|
### The Light Builder API Is Gone
|
|
90
99
|
|
|
91
100
|
`Light#with` and the whole `with_*` family are removed: `with_data_store`, `with_cool_off_time`, `with_threshold`,
|
|
@@ -250,6 +259,31 @@ Stoplight::DataStore::Redis.new(redis)
|
|
|
250
259
|
All time-dependent decisions are now made from Redis's own clock, so every instance reads the same time no matter
|
|
251
260
|
what its host believes. With the coordination problem solved at the source, there is no skew left to warn about.
|
|
252
261
|
|
|
262
|
+
### Colors and Lock States Are Symbols
|
|
263
|
+
|
|
264
|
+
`light.color` now returns `:green`, `:yellow`, or `:red` instead of `"green"`, `"yellow"`, or `"red"`, and
|
|
265
|
+
`light.state` returns `:unlocked`, `:locked_green`, or `:locked_red`. The constants under `Stoplight::Color` and
|
|
266
|
+
`Stoplight::State` hold the same symbols, and every telemetry event carries them too: `from_color` and `to_color` on
|
|
267
|
+
each transition, `from_state` and `to_state` on `LockChanged`.
|
|
268
|
+
|
|
269
|
+
`light.lock` only recognises the symbols, so `light.lock("red")` now raises `Stoplight::Error::IncorrectColor`.
|
|
270
|
+
|
|
271
|
+
Code that compares against the constants keeps working. Code that compares against, or passes, string literals needs
|
|
272
|
+
updating:
|
|
273
|
+
|
|
274
|
+
```ruby
|
|
275
|
+
# Old way that won't work anymore
|
|
276
|
+
alert! if light.color == "red"
|
|
277
|
+
light.lock("green")
|
|
278
|
+
|
|
279
|
+
# New way
|
|
280
|
+
alert! if light.color == Stoplight::Color::RED
|
|
281
|
+
light.lock(Stoplight::Color::GREEN)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Symbols are the idiomatic Ruby choice for a closed set of values. Anything that serializes them - logs, metrics tags,
|
|
285
|
+
the Admin dashboard's JSON - renders the same text as before.
|
|
286
|
+
|
|
253
287
|
### Getting Help
|
|
254
288
|
|
|
255
289
|
If you run into anything this guide doesn't cover, post to our [Discussions forum]. The configuration errors in 6.0
|
|
@@ -556,6 +590,7 @@ Nothing. Stoplight will function as usual.
|
|
|
556
590
|
[Community-supported notifiers]: https://github.com/bolshakov/stoplight/tree/master#community-supported-notifiers
|
|
557
591
|
[How to implement your own notifier?]: https://github.com/bolshakov/stoplight/blob/master/lib/stoplight/notifier/generic.rb
|
|
558
592
|
[dropped notifiers]: https://github.com/bolshakov/stoplight/tree/v3.0.1/lib/stoplight/notifier
|
|
593
|
+
[maintenance policy]: https://github.com/bolshakov/stoplight#maintenance-policy
|
|
559
594
|
[without passing an empty block]: https://github.com/bolshakov/stoplight-admin/blob/9c9848eb94410e46b20972548f0863db224cb6da/lib/sinatra/stoplight_admin.rb#L30
|
|
560
595
|
[sliding window]: https://github.com/bolshakov/stoplight#custom-window-size
|
|
561
596
|
[systems]: https://github.com/bolshakov/stoplight/blob/master/docs/systems.md
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
</p>
|
|
29
29
|
<span class="flex items-center text-sm font-medium text-gray-500 dark:text-gray-400 truncate me-3">
|
|
30
30
|
<span class="flex w-2.5 h-2.5 bg-<%= color %>-600 rounded-full me-1.5 shrink-0"></span>
|
|
31
|
-
<% if light
|
|
31
|
+
<% if red?(light) %>
|
|
32
32
|
Open
|
|
33
|
-
<% elsif light
|
|
33
|
+
<% elsif yellow?(light) %>
|
|
34
34
|
Half-Open
|
|
35
35
|
<% else %>
|
|
36
36
|
Closed
|
|
37
37
|
<% end %>
|
|
38
38
|
|
|
39
|
-
<% if light
|
|
39
|
+
<% if yellow?(light) %>
|
|
40
40
|
(Recovering)
|
|
41
41
|
<% elsif light.locked? %>
|
|
42
42
|
(Locked)
|
data/lib/stoplight/admin.rb
CHANGED
|
@@ -142,14 +142,14 @@ module Stoplight
|
|
|
142
142
|
|
|
143
143
|
patch "/systems/:system_id/lights/:light_id/lock" do
|
|
144
144
|
light_id = T.must(params[:light_id])
|
|
145
|
-
color = T.must(params[:color])
|
|
145
|
+
color = T.must(params[:color]).to_sym
|
|
146
146
|
dependencies.lock_action.call(light_id:, color:)
|
|
147
147
|
|
|
148
148
|
redirect system_url(current_system_id, "/lights")
|
|
149
149
|
end
|
|
150
150
|
|
|
151
151
|
patch "/systems/:system_id/lights/lock" do
|
|
152
|
-
color = T.must(params[:color])
|
|
152
|
+
color = T.must(params[:color]).to_sym
|
|
153
153
|
dependencies.lock_all_action.call(color:)
|
|
154
154
|
|
|
155
155
|
redirect system_url(current_system_id, "/lights")
|
data/lib/stoplight/color.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Stoplight
|
|
|
23
23
|
# @!attribute time
|
|
24
24
|
# The time when the snapshot was taken
|
|
25
25
|
|
|
26
|
-
# @return [
|
|
26
|
+
# @return [Symbol] one of +Color::GREEN+, +Color::RED+, or +Color::YELLOW+
|
|
27
27
|
def color
|
|
28
28
|
if locked_state == State::LOCKED_GREEN
|
|
29
29
|
Color::GREEN
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
-- @include now
|
|
2
2
|
|
|
3
3
|
local meta_key = KEYS[1]
|
|
4
|
-
local
|
|
4
|
+
local cool_off_time = tonumber(ARGV[1])
|
|
5
5
|
local current_ts = now() / 1000
|
|
6
|
+
local recovery_scheduled_after_ts = current_ts + cool_off_time
|
|
6
7
|
|
|
7
8
|
-- 1 if the field is a new field in the hash and the value was set
|
|
8
9
|
local became_red = redis.call('HSETNX', meta_key, 'breached_at', current_ts)
|
|
@@ -57,16 +57,19 @@ module Stoplight
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def state_snapshot
|
|
60
|
-
breached_at_raw, locked_state, recovery_scheduled_after_raw, recovery_started_at_raw =
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
breached_at_raw, locked_state, recovery_scheduled_after_raw, recovery_started_at_raw, now_ms =
|
|
61
|
+
scripting.call(
|
|
62
|
+
"state/state_snapshot",
|
|
63
|
+
args: [],
|
|
64
|
+
keys: [state_key]
|
|
65
|
+
)
|
|
63
66
|
|
|
64
67
|
Domain::StateSnapshot.new(
|
|
65
68
|
breached_at: breached_at_raw && clock.at(breached_at_raw.to_f),
|
|
66
|
-
locked_state: locked_state || Stoplight::State::UNLOCKED,
|
|
69
|
+
locked_state: locked_state&.to_sym || Stoplight::State::UNLOCKED,
|
|
67
70
|
recovery_scheduled_after: recovery_scheduled_after_raw && clock.at(recovery_scheduled_after_raw.to_f),
|
|
68
71
|
recovery_started_at: recovery_started_at_raw && clock.at(recovery_started_at_raw.to_f),
|
|
69
|
-
time: clock.
|
|
72
|
+
time: clock.at(now_ms.fdiv(1000))
|
|
70
73
|
)
|
|
71
74
|
end
|
|
72
75
|
|
|
@@ -123,12 +126,9 @@ module Stoplight
|
|
|
123
126
|
# Transitions to RED state and ensures only one notification
|
|
124
127
|
#
|
|
125
128
|
def transition_to_red
|
|
126
|
-
current_ts = clock.current_time.to_f
|
|
127
|
-
recovery_scheduled_after_ts = current_ts + cool_off_time
|
|
128
|
-
|
|
129
129
|
became_red = scripting.call(
|
|
130
130
|
"state/transition_to_red",
|
|
131
|
-
args: [
|
|
131
|
+
args: [cool_off_time],
|
|
132
132
|
keys: [state_key]
|
|
133
133
|
)
|
|
134
134
|
|
|
@@ -18,6 +18,8 @@ local function evict_buckets(metrics_key, ts_index_key, window_start)
|
|
|
18
18
|
return
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
local failures, successes = 0, 0
|
|
22
|
+
|
|
21
23
|
for from = 1, #buckets, EVICT_BATCH_SIZE do
|
|
22
24
|
local to = math.min(from + EVICT_BATCH_SIZE - 1, #buckets)
|
|
23
25
|
|
|
@@ -29,16 +31,15 @@ local function evict_buckets(metrics_key, ts_index_key, window_start)
|
|
|
29
31
|
|
|
30
32
|
local values = redis.call('HMGET', metrics_key, unpack(fields))
|
|
31
33
|
|
|
32
|
-
local failures, successes = 0, 0
|
|
33
34
|
for i = 1, #values, 2 do
|
|
34
35
|
failures = failures + (tonumber(values[i]) or 0)
|
|
35
36
|
successes = successes + (tonumber(values[i + 1]) or 0)
|
|
36
37
|
end
|
|
37
38
|
|
|
38
|
-
redis.call('HINCRBY', metrics_key, 'total_failures', -failures)
|
|
39
|
-
redis.call('HINCRBY', metrics_key, 'total_successes', -successes)
|
|
40
39
|
redis.call('HDEL', metrics_key, unpack(fields))
|
|
41
40
|
end
|
|
42
41
|
|
|
42
|
+
redis.call('HINCRBY', metrics_key, 'total_failures', -failures)
|
|
43
|
+
redis.call('HINCRBY', metrics_key, 'total_successes', -successes)
|
|
43
44
|
redis.call('ZREMRANGEBYSCORE', ts_index_key, '-inf', window_start)
|
|
44
45
|
end
|
data/lib/stoplight/state.rb
CHANGED
data/lib/stoplight/version.rb
CHANGED
|
@@ -46,6 +46,9 @@ module Stoplight
|
|
|
46
46
|
REGISTRATION_FRAME_LIMIT = 5
|
|
47
47
|
private_constant :REGISTRATION_FRAME_LIMIT
|
|
48
48
|
|
|
49
|
+
Registration = Data.define(:light, :digest, :backtrace, :without_settings)
|
|
50
|
+
private_constant :Registration
|
|
51
|
+
|
|
49
52
|
attr_reader :name
|
|
50
53
|
# @api private
|
|
51
54
|
attr_reader :config
|
|
@@ -113,6 +116,16 @@ module Stoplight
|
|
|
113
116
|
traffic_control: T.undefined,
|
|
114
117
|
traffic_recovery: T.undefined
|
|
115
118
|
)
|
|
119
|
+
without_settings = cool_off_time.is_a?(Undefined) && threshold.is_a?(Undefined) &&
|
|
120
|
+
recovery_threshold.is_a?(Undefined) && window_size.is_a?(Undefined) &&
|
|
121
|
+
tracked_errors.is_a?(Undefined) && skipped_errors.is_a?(Undefined) &&
|
|
122
|
+
traffic_control.is_a?(Undefined) && traffic_recovery.is_a?(Undefined)
|
|
123
|
+
|
|
124
|
+
if without_settings
|
|
125
|
+
registration = @lights[name]
|
|
126
|
+
return registration.light if registration&.without_settings
|
|
127
|
+
end
|
|
128
|
+
|
|
116
129
|
light_dsl = LightConfigurationDsl.new(
|
|
117
130
|
name:,
|
|
118
131
|
cool_off_time:,
|
|
@@ -126,8 +139,8 @@ module Stoplight
|
|
|
126
139
|
)
|
|
127
140
|
config_digest = light_dsl.digest
|
|
128
141
|
|
|
129
|
-
|
|
130
|
-
|
|
142
|
+
registration = @lights[name] || begin
|
|
143
|
+
backtrace = ExternalCaller.backtrace.first(REGISTRATION_FRAME_LIMIT)
|
|
131
144
|
config = light_dsl.configure!(@config)
|
|
132
145
|
@lights.compute_if_absent(name) do
|
|
133
146
|
built = LightFactory.new(
|
|
@@ -137,12 +150,12 @@ module Stoplight
|
|
|
137
150
|
telemetry: @telemetry
|
|
138
151
|
).build
|
|
139
152
|
@registry.register(config)
|
|
140
|
-
|
|
153
|
+
Registration.new(light: built, digest: config_digest, backtrace:, without_settings:)
|
|
141
154
|
end
|
|
142
155
|
end
|
|
143
156
|
|
|
144
|
-
if config_digest !=
|
|
145
|
-
original_site =
|
|
157
|
+
if config_digest != registration.digest
|
|
158
|
+
original_site = registration.backtrace.map { |frame| " #{frame}" }.join("\n")
|
|
146
159
|
|
|
147
160
|
raise Stoplight::Error::ConfigurationError, <<~MSG, ExternalCaller.backtrace
|
|
148
161
|
Light `#{name}` already registered with different configuration.
|
|
@@ -154,12 +167,12 @@ module Stoplight
|
|
|
154
167
|
MSG
|
|
155
168
|
end
|
|
156
169
|
|
|
157
|
-
light
|
|
170
|
+
registration.light
|
|
158
171
|
end
|
|
159
172
|
|
|
160
173
|
# @raise [Stoplight::Error::UnregisteredLightError] if no light was registered under +name+
|
|
161
174
|
def light(name)
|
|
162
|
-
@lights[name]&.
|
|
175
|
+
@lights[name]&.light || raise(Stoplight::Error::UnregisteredLightError, <<~MSG)
|
|
163
176
|
Light `#{name}` was never registered on system `#{@name}`.
|
|
164
177
|
Call `.register(#{name.inspect}, ...)` at boot before using it.
|
|
165
178
|
MSG
|
|
@@ -3,6 +3,9 @@ module Stoplight
|
|
|
3
3
|
module Helpers : Sinatra::Base
|
|
4
4
|
COLORS: Array[Domain::color]
|
|
5
5
|
|
|
6
|
+
def red?: (LightView) -> bool
|
|
7
|
+
def yellow?: (LightView) -> bool
|
|
8
|
+
|
|
6
9
|
def dependencies: -> Dependencies
|
|
7
10
|
def system_url: (String system_id, String path) -> String
|
|
8
11
|
def asset_path: (String) -> String
|
|
@@ -5,15 +5,15 @@ module Stoplight
|
|
|
5
5
|
type duration_ms = Float
|
|
6
6
|
|
|
7
7
|
# Light Colors
|
|
8
|
-
type green =
|
|
9
|
-
type yellow =
|
|
10
|
-
type red =
|
|
8
|
+
type green = :green
|
|
9
|
+
type yellow = :yellow
|
|
10
|
+
type red = :red
|
|
11
11
|
type color = green | yellow | red
|
|
12
12
|
|
|
13
13
|
# Light States
|
|
14
|
-
type unlocked =
|
|
15
|
-
type locked_green =
|
|
16
|
-
type locked_red =
|
|
14
|
+
type unlocked = :unlocked
|
|
15
|
+
type locked_green = :locked_green
|
|
16
|
+
type locked_red = :locked_red
|
|
17
17
|
type state = unlocked | locked_green | locked_red
|
|
18
18
|
|
|
19
19
|
type recovery_decision = :green | :yellow | :red
|
|
@@ -9,7 +9,7 @@ module Stoplight
|
|
|
9
9
|
attr_reader scripting: Scripting
|
|
10
10
|
attr_reader key_space: Key
|
|
11
11
|
attr_reader clock: Domain::_Clock
|
|
12
|
-
attr_reader cool_off_time: Domain::
|
|
12
|
+
attr_reader cool_off_time: Domain::duration_seconds
|
|
13
13
|
attr_reader state_key: String
|
|
14
14
|
|
|
15
15
|
def initialize: (
|
|
@@ -17,7 +17,7 @@ module Stoplight
|
|
|
17
17
|
redis: redis,
|
|
18
18
|
scripting: Scripting,
|
|
19
19
|
key_space: Key,
|
|
20
|
-
cool_off_time: Domain::
|
|
20
|
+
cool_off_time: Domain::duration_seconds
|
|
21
21
|
) -> void
|
|
22
22
|
|
|
23
23
|
def transition_to_green: -> bool
|
|
@@ -6,7 +6,28 @@ module Stoplight
|
|
|
6
6
|
@name: String
|
|
7
7
|
REGISTRATION_FRAME_LIMIT: Integer
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
class Registration < Data
|
|
10
|
+
attr_reader light: Domain::Light
|
|
11
|
+
attr_reader digest: Integer
|
|
12
|
+
attr_reader backtrace: Array[String]
|
|
13
|
+
attr_reader without_settings: bool
|
|
14
|
+
|
|
15
|
+
def self.new: (
|
|
16
|
+
light: Domain::Light,
|
|
17
|
+
digest: Integer,
|
|
18
|
+
backtrace: Array[String],
|
|
19
|
+
without_settings: bool,
|
|
20
|
+
) -> instance
|
|
21
|
+
|
|
22
|
+
def initialize: (
|
|
23
|
+
light: Domain::Light,
|
|
24
|
+
digest: Integer,
|
|
25
|
+
backtrace: Array[String],
|
|
26
|
+
without_settings: bool,
|
|
27
|
+
) -> void
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
@lights: Concurrent::Map[String, Registration]
|
|
10
31
|
@failover_system: _System?
|
|
11
32
|
@registry: Domain::_Registry
|
|
12
33
|
@telemetry: Domain::Telemetry::Bus
|
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.rc5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tëma Bolshakov
|
|
@@ -145,6 +145,7 @@ files:
|
|
|
145
145
|
- lib/stoplight/infrastructure/redis/storage/registry.rb
|
|
146
146
|
- lib/stoplight/infrastructure/redis/storage/scripting.rb
|
|
147
147
|
- lib/stoplight/infrastructure/redis/storage/state.rb
|
|
148
|
+
- lib/stoplight/infrastructure/redis/storage/state/state_snapshot.lua
|
|
148
149
|
- lib/stoplight/infrastructure/redis/storage/state/transition_to_green.lua
|
|
149
150
|
- lib/stoplight/infrastructure/redis/storage/state/transition_to_red.lua
|
|
150
151
|
- lib/stoplight/infrastructure/redis/storage/state/transition_to_yellow.lua
|