stoplight 5.0.2 → 5.1.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 +21 -3
- data/lib/generators/stoplight/install/USAGE +16 -0
- data/lib/generators/stoplight/install/install_generator.rb +75 -0
- data/lib/generators/stoplight/install/templates/stoplight.rb.erb +18 -0
- data/lib/stoplight/admin.rb +1 -2
- data/lib/stoplight/config/config_provider.rb +51 -2
- data/lib/stoplight/config/user_default_config.rb +7 -15
- data/lib/stoplight/data_store/fail_safe.rb +2 -0
- data/lib/stoplight/default.rb +1 -3
- data/lib/stoplight/light/config.rb +49 -102
- data/lib/stoplight/light.rb +3 -1
- data/lib/stoplight/traffic_control/base.rb +6 -0
- data/lib/stoplight/version.rb +1 -1
- data/lib/stoplight.rb +3 -2
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fba85e77b2b2c6569592f463080da2bca787dc65f12da00bf566b4bb7e56912
|
4
|
+
data.tar.gz: 4aaac27c0747de8a550575ecd8a93cc2391f3a73c008c543ee049db6f7fd01b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acc5305b5da510feacb9584a60a6043eb4c7c7280bbf6f3d6c77db968a445aa45fcfaaaf41027684ff9dc7f4ebf615b1f27e0d53315eda932126b6c47b5ca514
|
7
|
+
data.tar.gz: 1ce0b8d4fea66779d6688c52a871ac10568184f796fc3d51a08c9d6fb45e2402b59da077cbcdd049b1dcdc9e2e748ebdde9ebd327b28aa810190b6bf8d17049c
|
data/README.md
CHANGED
@@ -128,18 +128,23 @@ receives `nil`. In both cases, the return value of the fallback becomes the retu
|
|
128
128
|
|
129
129
|
Stoplight goes with a built-in Admin Panel that can track all active Lights and manually lock them in the desired state (`Green` or `Red`). Locking lights in certain states might be helpful in scenarios like E2E testing.
|
130
130
|
|
131
|
-
To add Admin Panel to your Rails project, add this configuration to your `config/routes.rb` file.
|
131
|
+
To add Admin Panel protected by basic authentication to your Rails project, add this configuration to your `config/routes.rb` file.
|
132
132
|
|
133
133
|
```ruby
|
134
134
|
Rails.application.routes.draw do
|
135
135
|
# ...
|
136
136
|
|
137
|
+
Stoplight::Admin.use(Rack::Auth::Basic) do |username, password|
|
138
|
+
username == ENV["STOPLIGHT_ADMIN_USERNAME"] && password == ENV["STOPLIGHT_ADMIN_PASSWORD"]
|
139
|
+
end
|
137
140
|
mount Stoplight::Admin => '/stoplights'
|
138
141
|
|
139
142
|
# ...
|
140
143
|
end
|
141
144
|
```
|
142
145
|
|
146
|
+
Then set up `STOPLIGHT_ADMIN_USERNAME` and `STOPLIGHT_ADMIN_PASSWORD` env variables to access your Admin panel.
|
147
|
+
|
143
148
|
**IMPORTANT:** Stoplight Admin Panel requires you to have `sinatra` and `sinatra-contrib` gems installed. You can either add them to your Gemfile:
|
144
149
|
|
145
150
|
```ruby
|
@@ -158,13 +163,13 @@ gem install sinatra-contrib
|
|
158
163
|
It is possible to run the Admin Panel separately from your application using the `stoplight-admin:<release-version>` docker image.
|
159
164
|
|
160
165
|
```shell
|
161
|
-
docker run --net=host stoplight-admin
|
166
|
+
docker run --net=host bolshakov/stoplight-admin
|
162
167
|
```
|
163
168
|
|
164
169
|
**IMPORTANT:** Standalone Admin Panel should use the same Redis your application uses. To achieve this, set the `REDIS_URL` ENV variable via `-e REDIS_URL=<url-to-your-redis-servier>.` E.g.:
|
165
170
|
|
166
171
|
```shell
|
167
|
-
docker run -e REDIS_URL=redis://localhost:6378 --net=host stoplight-admin
|
172
|
+
docker run -e REDIS_URL=redis://localhost:6378 --net=host bolshakov/stoplight-admin
|
168
173
|
```
|
169
174
|
|
170
175
|
|
@@ -384,6 +389,12 @@ Stoplight.configure do |config|
|
|
384
389
|
end
|
385
390
|
```
|
386
391
|
|
392
|
+
You can generate initializer with Redis, Admin Panel route and add needed gems to your Gemfile:
|
393
|
+
|
394
|
+
```sh
|
395
|
+
rails generate stoplight:install --with-admin-panel
|
396
|
+
```
|
397
|
+
|
387
398
|
## Testing
|
388
399
|
|
389
400
|
Tips for working with Stoplight in test environments:
|
@@ -416,6 +427,12 @@ Stoplight supports the latest three minor versions of Ruby, which currently are:
|
|
416
427
|
the minimum supported Ruby version is not considered a breaking change. We support the current stable Redis
|
417
428
|
version (`7.4.x`) and the latest release of the previous major version (`6.2.x`)
|
418
429
|
|
430
|
+
## Development
|
431
|
+
|
432
|
+
After checking out the repo, run `bundle install` to install dependencies. Run tests with `bundle exec rspec` and check
|
433
|
+
code style with `bundle exec standardrb`. We follow a git flow branching strategy - see our [Git Flow wiki page] for
|
434
|
+
details on branch naming, releases, and contribution workflow.
|
435
|
+
|
419
436
|
## Credits
|
420
437
|
|
421
438
|
Stoplight was originally created by [camdez][] and [tfausak][]. It is currently maintained by [bolshakov][] and
|
@@ -444,3 +461,4 @@ Fowler’s [CircuitBreaker][] article.
|
|
444
461
|
[complete list of contributors]: https://github.com/bolshakov/stoplight/graphs/contributors
|
445
462
|
[CircuitBreaker]: http://martinfowler.com/bliki/CircuitBreaker.html
|
446
463
|
[Redis]: https://redis.io/
|
464
|
+
[Git Flow wiki page]: https://github.com/bolshakov/stoplight/wiki/Git-Flow
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Description:
|
2
|
+
Generates stoplight initializer to setup Stoplight Redis configuration
|
3
|
+
and optionally sets up Admin panel
|
4
|
+
|
5
|
+
Examples:
|
6
|
+
rails generate stoplight:install
|
7
|
+
|
8
|
+
This will generate "config/initializers/stoplight.rb" initializer with basic config
|
9
|
+
Then you should adjust Redis config there.
|
10
|
+
|
11
|
+
rails generate stoplight:install --with-admin-panel
|
12
|
+
|
13
|
+
This generated all needed requirements to set up Stoplight Admin Panel:
|
14
|
+
* It generates initializer "config/initializers/stoplight.rb" with Redis configuration
|
15
|
+
* It injects your "config/routes.rb" with route with basic authentication to Stoplight Admin panel
|
16
|
+
* It injects your Gemfile with needed dependencies ('redis', 'sinatra' and 'sinatra-contrib')
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "rails/generators"
|
5
|
+
rescue LoadError
|
6
|
+
raise <<~WARN
|
7
|
+
Currently generators are only available for Rails applications
|
8
|
+
WARN
|
9
|
+
end
|
10
|
+
|
11
|
+
module Stoplight
|
12
|
+
module Generators
|
13
|
+
class InstallGenerator < ::Rails::Generators::Base # :nodoc:
|
14
|
+
source_root File.expand_path("templates", __dir__)
|
15
|
+
|
16
|
+
class_option :with_admin_panel, type: :boolean, optional: true,
|
17
|
+
desc: "Define whether to set up admin panel"
|
18
|
+
|
19
|
+
ROUTES_PATH = "config/routes.rb"
|
20
|
+
STOPLIGHT_CONFIG_TEMPLATE = "stoplight.rb.erb"
|
21
|
+
INITIALIZERS_PATH = "config/initializers"
|
22
|
+
AFTER_INSTALL_NOTIFICATION = <<~TEXT
|
23
|
+
\nThank you for using stoplight!
|
24
|
+
Now to finish configuration:
|
25
|
+
* Run `bundle` from the project root to install new gems
|
26
|
+
* Go to 'config/initializers/stoplight.rb' to set up connection to Redis.\n
|
27
|
+
TEXT
|
28
|
+
|
29
|
+
STOPLIGHT_ADMIN_ROUTE = <<-RUBY
|
30
|
+
mount Stoplight::Admin => '/stoplights'
|
31
|
+
RUBY
|
32
|
+
|
33
|
+
STOPLIGHT_AUTH = <<-RUBY
|
34
|
+
Stoplight::Admin.use(Rack::Auth::Basic) do |username, password|
|
35
|
+
username == ENV["STOPLIGHT_ADMIN_USERNAME"] && password == ENV["STOPLIGHT_ADMIN_PASSWORD"]
|
36
|
+
end
|
37
|
+
RUBY
|
38
|
+
|
39
|
+
def generate_redis_gem
|
40
|
+
if options[:with_admin_panel]
|
41
|
+
conf = "\ngem 'redis'"
|
42
|
+
inject_into_file "Gemfile", conf
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def generate_sinatra_deps
|
47
|
+
if options[:with_admin_panel]
|
48
|
+
conf = <<~RUBY
|
49
|
+
gem 'sinatra', require: false
|
50
|
+
gem 'sinatra-contrib', require: false
|
51
|
+
RUBY
|
52
|
+
|
53
|
+
inject_into_file "Gemfile", "\n#{conf}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def generate_initializer
|
58
|
+
initializer_template = STOPLIGHT_CONFIG_TEMPLATE
|
59
|
+
copy_file initializer_template, "#{INITIALIZERS_PATH}/stoplight.rb"
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_admin_panel
|
63
|
+
if options[:with_admin_panel]
|
64
|
+
route_config = "#{STOPLIGHT_AUTH}#{STOPLIGHT_ADMIN_ROUTE}\n"
|
65
|
+
|
66
|
+
inject_into_file ROUTES_PATH, route_config, after: ".application.routes.draw do\n"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def redis_configuration_notification
|
71
|
+
print AFTER_INSTALL_NOTIFICATION
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "redis"
|
4
|
+
|
5
|
+
# Set up your project-specific Redis setup here
|
6
|
+
# One of the simplest configurations would be configuring Redis via url
|
7
|
+
# Example:
|
8
|
+
# redis = Redis.new(url: ENV["REDIS_URL"])
|
9
|
+
# REDIS_URL usually looks like this
|
10
|
+
# "redis://<username>:<password>@<server ip address>:<port>/<redis db>"
|
11
|
+
# Example:
|
12
|
+
# "redis://admin:p4ssw0rd@10.0.1.1:6380/15"
|
13
|
+
redis = Redis.new
|
14
|
+
data_store = Stoplight::DataStore::Redis.new(redis)
|
15
|
+
|
16
|
+
Stoplight.configure do |config|
|
17
|
+
config.data_store = data_store
|
18
|
+
end
|
data/lib/stoplight/admin.rb
CHANGED
@@ -10,6 +10,8 @@ module Stoplight
|
|
10
10
|
# 4. **Library-Level Default Settings**: Default settings defined in the +Stoplight::Config::UserDefaultConfig+ module.
|
11
11
|
#
|
12
12
|
# The settings are merged in this order, with higher-precedence settings overriding lower-precedence ones.
|
13
|
+
# After merging settings, the configuration transformations are applied such as wrapping data stores and notifiers
|
14
|
+
# with fail-safe mechanism, type conversion, etc. Each transformation must be idempotent.
|
13
15
|
#
|
14
16
|
# @api private
|
15
17
|
class ConfigProvider
|
@@ -38,13 +40,28 @@ module Stoplight
|
|
38
40
|
# @see +Stoplight()+
|
39
41
|
# @return [Stoplight::Light::Config] The configuration for the specified light.
|
40
42
|
# @raise [Error::ConfigurationError]
|
41
|
-
def provide(light_name,
|
43
|
+
def provide(light_name, settings_overrides = {})
|
42
44
|
raise Error::ConfigurationError, <<~ERROR if settings_overrides.has_key?(:name)
|
43
45
|
The +name+ setting cannot be overridden in the configuration.
|
44
46
|
ERROR
|
45
47
|
|
46
48
|
settings = default_settings.merge(settings_overrides, {name: light_name})
|
47
|
-
Light::Config.new(**settings)
|
49
|
+
Light::Config.new(**transform_settings(settings))
|
50
|
+
end
|
51
|
+
|
52
|
+
# Creates a configuration from a given +Stoplight::Light::Config+ object extending it
|
53
|
+
# with additional settings overrides.
|
54
|
+
#
|
55
|
+
# @param config [Stoplight::Light::Config] The configuration object to extend.
|
56
|
+
# @param settings_overrides [Hash] The settings to override.
|
57
|
+
# @return [Stoplight::Light::Config] The new extended configuration object.
|
58
|
+
def from_prototype(config, settings_overrides)
|
59
|
+
config.to_h.then do |settings|
|
60
|
+
current_name = settings.delete(:name)
|
61
|
+
name = settings_overrides.delete(:name) || current_name
|
62
|
+
|
63
|
+
provide(name, **settings.merge(settings_overrides))
|
64
|
+
end
|
48
65
|
end
|
49
66
|
|
50
67
|
def inspect
|
@@ -57,6 +74,38 @@ module Stoplight
|
|
57
74
|
"data_store=#{default_settings[:data_store].class.name}" \
|
58
75
|
">"
|
59
76
|
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def transform_settings(settings)
|
81
|
+
settings.merge(
|
82
|
+
data_store: build_data_store(settings.fetch(:data_store)),
|
83
|
+
notifiers: build_notifiers(settings.fetch(:notifiers)),
|
84
|
+
tracked_errors: build_tracked_errors(settings.fetch(:tracked_errors)),
|
85
|
+
skipped_errors: build_skipped_errors(settings.fetch(:skipped_errors)),
|
86
|
+
cool_off_time: build_cool_off_time(settings.fetch(:cool_off_time))
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_data_store(data_store)
|
91
|
+
DataStore::FailSafe.wrap(data_store)
|
92
|
+
end
|
93
|
+
|
94
|
+
def build_notifiers(notifiers)
|
95
|
+
notifiers.map { |notifier| Notifier::FailSafe.wrap(notifier) }
|
96
|
+
end
|
97
|
+
|
98
|
+
def build_tracked_errors(tracked_error)
|
99
|
+
Array(tracked_error)
|
100
|
+
end
|
101
|
+
|
102
|
+
def build_skipped_errors(skipped_errors)
|
103
|
+
Array(skipped_errors)
|
104
|
+
end
|
105
|
+
|
106
|
+
def build_cool_off_time(cool_off_time)
|
107
|
+
cool_off_time.to_i
|
108
|
+
end
|
60
109
|
end
|
61
110
|
end
|
62
111
|
end
|
@@ -20,9 +20,9 @@ module Stoplight
|
|
20
20
|
# @return [Proc, nil] The default error notifier (callable object).
|
21
21
|
attr_writer :error_notifier
|
22
22
|
|
23
|
-
# @!attribute [
|
23
|
+
# @!attribute [rw] notifiers
|
24
24
|
# @return [Array<Stoplight::Notifier::Base>] The default list of notifiers.
|
25
|
-
|
25
|
+
attr_accessor :notifiers
|
26
26
|
|
27
27
|
# @!attribute [w] threshold
|
28
28
|
# @return [Integer, nil] The default failure threshold to trip the circuit breaker.
|
@@ -40,24 +40,16 @@ module Stoplight
|
|
40
40
|
# @return [Array<Class>, nil] The default list of errors to skip.
|
41
41
|
attr_writer :skipped_errors
|
42
42
|
|
43
|
+
# @!attribute [w] data_store
|
44
|
+
# @return [Stoplight::DataStore::Base] The default data store instance.
|
45
|
+
attr_writer :data_store
|
46
|
+
|
43
47
|
def initialize
|
44
48
|
# This allows users appending notifiers to the default list,
|
45
49
|
# while still allowing them to override the default list.
|
46
50
|
@notifiers = Default::NOTIFIERS
|
47
51
|
end
|
48
52
|
|
49
|
-
# @param value [Stoplight::DataStore::Base]
|
50
|
-
# @return [Stoplight::DataStore::Base] The default data store instance.
|
51
|
-
def data_store=(value)
|
52
|
-
@data_store = DataStore::FailSafe.wrap(value)
|
53
|
-
end
|
54
|
-
|
55
|
-
# @param value [Array<Stoplight::Notifier::Base>]
|
56
|
-
# @return [Array<Stoplight::Notifier::FailSafe>]
|
57
|
-
def notifiers=(value)
|
58
|
-
@notifiers = value.map { |notifier| Notifier::FailSafe.wrap(notifier) }
|
59
|
-
end
|
60
|
-
|
61
53
|
# Converts the user-defined configuration to a hash.
|
62
54
|
#
|
63
55
|
# @return [Hash] A hash representation of the configuration, excluding nil values.
|
@@ -67,7 +59,7 @@ module Stoplight
|
|
67
59
|
cool_off_time: @cool_off_time,
|
68
60
|
data_store: @data_store,
|
69
61
|
error_notifier: @error_notifier,
|
70
|
-
notifiers:
|
62
|
+
notifiers: @notifiers,
|
71
63
|
threshold: @threshold,
|
72
64
|
window_size: @window_size,
|
73
65
|
tracked_errors: @tracked_errors,
|
data/lib/stoplight/default.rb
CHANGED
@@ -3,85 +3,56 @@
|
|
3
3
|
module Stoplight
|
4
4
|
class Light
|
5
5
|
# A +Stoplight::Light+ configuration object.
|
6
|
+
#
|
7
|
+
# # @!attribute [r] name
|
8
|
+
# @return [String]
|
9
|
+
#
|
10
|
+
# @!attribute [r] cool_off_time
|
11
|
+
# @return [Numeric]
|
12
|
+
#
|
13
|
+
# @!attribute [r] data_store
|
14
|
+
# @return [Stoplight::DataStore::Base]
|
15
|
+
#
|
16
|
+
# @!attribute [r] error_notifier
|
17
|
+
# @return [StandardError => void]
|
18
|
+
#
|
19
|
+
# @!attribute [r] notifiers
|
20
|
+
# @return [Array<Stoplight::Notifier::Base>]
|
21
|
+
#
|
22
|
+
# @!attribute [r] threshold
|
23
|
+
# @return [Numeric]
|
24
|
+
#
|
25
|
+
# @!attribute [r] window_size
|
26
|
+
# @return [Numeric]
|
27
|
+
#
|
28
|
+
# @!attribute [r] tracked_errors
|
29
|
+
# @return [Array<StandardError>]
|
30
|
+
#
|
31
|
+
# @!attribute [r] skipped_errors
|
32
|
+
# @return [Array<Exception>]
|
33
|
+
#
|
34
|
+
# @!attribute [r] traffic_control
|
35
|
+
# @return [Stoplight::TrafficControl::Base]
|
36
|
+
#
|
37
|
+
# @!attribute [r] traffic_recovery
|
38
|
+
# @return [Stoplight::TrafficRecovery::Base]
|
6
39
|
# @api private
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
#
|
21
|
-
#
|
22
|
-
|
23
|
-
|
24
|
-
# @!attribute [r] notifiers
|
25
|
-
# @return [Array<Stoplight::Notifier::Base>]
|
26
|
-
attr_reader :notifiers
|
27
|
-
|
28
|
-
# @!attribute [r] threshold
|
29
|
-
# @return [Numeric]
|
30
|
-
attr_reader :threshold
|
31
|
-
|
32
|
-
# @!attribute [r] window_size
|
33
|
-
# @return [Numeric]
|
34
|
-
attr_reader :window_size
|
35
|
-
|
36
|
-
# @!attribute [r] tracked_errors
|
37
|
-
# @return [Array<StandardError>]
|
38
|
-
attr_reader :tracked_errors
|
39
|
-
|
40
|
-
# @!attribute [r] skipped_errors
|
41
|
-
# @return [Array<Exception>]
|
42
|
-
attr_reader :skipped_errors
|
43
|
-
|
44
|
-
# @!attribute [r] traffic_control
|
45
|
-
# @return [Stoplight::TrafficControl::Base]
|
46
|
-
attr_reader :traffic_control
|
47
|
-
|
48
|
-
# @!attribute [r] traffic_recovery
|
49
|
-
# @return [Stoplight::TrafficRecovery::Base]
|
50
|
-
attr_reader :traffic_recovery
|
51
|
-
|
52
|
-
# @param name [String]
|
53
|
-
# @param cool_off_time [Numeric]
|
54
|
-
# @param data_store [Stoplight::DataStore::Base]
|
55
|
-
# @param error_notifier [Proc]
|
56
|
-
# @param notifiers [Array<Stoplight::Notifier::Base>]
|
57
|
-
# @param threshold [Numeric]
|
58
|
-
# @param window_size [Numeric]
|
59
|
-
# @param tracked_errors [Array<StandardError>]
|
60
|
-
# @param skipped_errors [Array<Exception>]
|
61
|
-
# @param traffic_control [Stoplight::TrafficControl::Base]
|
62
|
-
# @param traffic_recovery [Stoplight::TrafficRecovery::Base]
|
63
|
-
def initialize(name:, cool_off_time:, data_store:, error_notifier:, notifiers:, threshold:, window_size:,
|
64
|
-
tracked_errors:, skipped_errors:, traffic_control:, traffic_recovery:)
|
65
|
-
@name = name
|
66
|
-
@cool_off_time = cool_off_time.to_i
|
67
|
-
@data_store = DataStore::FailSafe.wrap(data_store)
|
68
|
-
@error_notifier = error_notifier
|
69
|
-
@notifiers = notifiers.map { |notifier| Notifier::FailSafe.wrap(notifier) }
|
70
|
-
@threshold = threshold
|
71
|
-
@window_size = window_size
|
72
|
-
@tracked_errors = Array(tracked_errors)
|
73
|
-
@skipped_errors = Array(skipped_errors)
|
74
|
-
@traffic_control = traffic_control
|
75
|
-
@traffic_recovery = traffic_recovery
|
76
|
-
end
|
77
|
-
|
78
|
-
# @param other [any]
|
79
|
-
# @return [Boolean]
|
80
|
-
def ==(other)
|
81
|
-
other.is_a?(self.class) && to_h == other.to_h
|
82
|
-
end
|
83
|
-
|
84
|
-
# @param error [Exception]
|
40
|
+
Config = Data.define(
|
41
|
+
:name,
|
42
|
+
:cool_off_time,
|
43
|
+
:data_store,
|
44
|
+
:error_notifier,
|
45
|
+
:notifiers,
|
46
|
+
:threshold,
|
47
|
+
:window_size,
|
48
|
+
:tracked_errors,
|
49
|
+
:skipped_errors,
|
50
|
+
:traffic_control,
|
51
|
+
:traffic_recovery
|
52
|
+
) do
|
53
|
+
# Checks if the given error should be tracked
|
54
|
+
#
|
55
|
+
# @param error [#==] The error to check, e.g. an Exception, Class or Proc
|
85
56
|
# @return [Boolean]
|
86
57
|
def track_error?(error)
|
87
58
|
skip = skipped_errors.any? { |klass| klass === error }
|
@@ -89,30 +60,6 @@ module Stoplight
|
|
89
60
|
|
90
61
|
!skip && track
|
91
62
|
end
|
92
|
-
|
93
|
-
# Updates the configuration with new settings and returns a new instance.
|
94
|
-
#
|
95
|
-
# @return [Stoplight::Light::Config]
|
96
|
-
def with(**settings)
|
97
|
-
self.class.new(**to_h.merge(settings))
|
98
|
-
end
|
99
|
-
|
100
|
-
# @return [Hash]
|
101
|
-
def to_h
|
102
|
-
{
|
103
|
-
cool_off_time:,
|
104
|
-
data_store:,
|
105
|
-
error_notifier:,
|
106
|
-
name:,
|
107
|
-
notifiers:,
|
108
|
-
threshold:,
|
109
|
-
window_size:,
|
110
|
-
tracked_errors:,
|
111
|
-
skipped_errors:,
|
112
|
-
traffic_control:,
|
113
|
-
traffic_recovery:
|
114
|
-
}
|
115
|
-
end
|
116
63
|
end
|
117
64
|
end
|
118
65
|
end
|
data/lib/stoplight/light.rb
CHANGED
@@ -150,7 +150,9 @@ module Stoplight
|
|
150
150
|
# payment_light.run(->(error) { nil }) { call_payment_api }
|
151
151
|
# @see +Stoplight()+
|
152
152
|
def with(**settings)
|
153
|
-
reconfigure(
|
153
|
+
reconfigure(
|
154
|
+
Stoplight.config_provider.from_prototype(config, settings)
|
155
|
+
)
|
154
156
|
end
|
155
157
|
|
156
158
|
private
|
data/lib/stoplight/version.rb
CHANGED
data/lib/stoplight.rb
CHANGED
@@ -9,6 +9,7 @@ loader.do_not_eager_load(
|
|
9
9
|
"#{__dir__}/stoplight/admin",
|
10
10
|
"#{__dir__}/stoplight/admin.rb"
|
11
11
|
)
|
12
|
+
loader.ignore("#{__dir__}/generators")
|
12
13
|
loader.ignore("#{__dir__}/stoplight/rspec.rb", "#{__dir__}/stoplight/rspec")
|
13
14
|
loader.setup
|
14
15
|
|
@@ -26,7 +27,7 @@ module Stoplight # rubocop:disable Style/Documentation
|
|
26
27
|
# It raises an error if called more than once.
|
27
28
|
#
|
28
29
|
# @yield [config] Provides a configuration object to the block.
|
29
|
-
# @yieldparam config [Stoplight::Config::
|
30
|
+
# @yieldparam config [Stoplight::Config::UserDefaultConfig] The configuration object.
|
30
31
|
# @raise [Stoplight::Error::ConfigurationError] If the library is already configured.
|
31
32
|
# @return [void]
|
32
33
|
#
|
@@ -118,6 +119,6 @@ end
|
|
118
119
|
# light = Stoplight("Payment API", skipped_errors: [ActiveRecord::RecordNotFound])
|
119
120
|
#
|
120
121
|
def Stoplight(name, **settings) # rubocop:disable Naming/MethodName
|
121
|
-
config = Stoplight.config_provider.provide(name,
|
122
|
+
config = Stoplight.config_provider.provide(name, settings)
|
122
123
|
Stoplight::Light.new(config)
|
123
124
|
end
|
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stoplight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Desautels
|
8
8
|
- Taylor Fausak
|
9
9
|
- Justin Steffy
|
10
|
+
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2025-06-
|
13
|
+
date: 2025-06-27 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: zeitwerk
|
@@ -37,6 +38,9 @@ files:
|
|
37
38
|
- CHANGELOG.md
|
38
39
|
- LICENSE.md
|
39
40
|
- README.md
|
41
|
+
- lib/generators/stoplight/install/USAGE
|
42
|
+
- lib/generators/stoplight/install/install_generator.rb
|
43
|
+
- lib/generators/stoplight/install/templates/stoplight.rb.erb
|
40
44
|
- lib/stoplight.rb
|
41
45
|
- lib/stoplight/admin.rb
|
42
46
|
- lib/stoplight/admin/actions/action.rb
|
@@ -98,6 +102,7 @@ homepage: https://github.com/bolshakov/stoplight
|
|
98
102
|
licenses:
|
99
103
|
- MIT
|
100
104
|
metadata: {}
|
105
|
+
post_install_message:
|
101
106
|
rdoc_options: []
|
102
107
|
require_paths:
|
103
108
|
- lib
|
@@ -112,7 +117,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
117
|
- !ruby/object:Gem::Version
|
113
118
|
version: '0'
|
114
119
|
requirements: []
|
115
|
-
rubygems_version: 3.
|
120
|
+
rubygems_version: 3.4.19
|
121
|
+
signing_key:
|
116
122
|
specification_version: 4
|
117
123
|
summary: Traffic control for code.
|
118
124
|
test_files: []
|