breakers 0.7.1 → 1.0.1

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: d07e3fb5d5ea487bfd3a050d06ec8e5094efcb604e18554be68f849cdb0bf5a7
4
- data.tar.gz: 4754bcc47f248d9f099dde4a9aaf494bfe47a6e9060ee592c84693e5eaceee2c
3
+ metadata.gz: 1471486e4b71db051dc6b073a4f5f98cd3a2bb6a10b51a3da6d12d24b1bba5f6
4
+ data.tar.gz: d7703097ccb4bb819a32c80c28cfabc6563520ffd7552961546873243ab2f125
5
5
  SHA512:
6
- metadata.gz: 0ff3ede40289743dc8f709dbcba90797b93d48b9e4ccf6215b61b0d45eb0dcb8bc04f7214d4cc8c3a53aa1e43f2318461729e24e1aebcd9490c0b137a3260ee8
7
- data.tar.gz: bc44523288871ac14ca612e46fe4bfe167219714bae37dcb7d2fc3c97fa9f894a669fffa70b5c4060629411309bc1ab16d089d1e4b9d03491e2ec7f2dde032fd
6
+ metadata.gz: b99274dd003feb7f3b362950844eca5f9b194b9a30b0959dfdf8003e4163752dc0400cf69d868069a816089467c6d529788de5b4024186fe1c52f0e70db43ebf
7
+ data.tar.gz: a112b8f32680017e9c98fbd55b122aa2ab30bc33a1a950e9e2c9236ca4d294df4b96338012dab8e4f23e5e0fb89dba04768b37ee43b9eff0e34a1bebb4e78a4a
@@ -0,0 +1,27 @@
1
+ name: Run RSpec Tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - name: Checkout code
15
+ uses: actions/checkout@v3
16
+
17
+ - name: Set up Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: '3.3.6'
21
+ bundler-cache: true
22
+
23
+ - name: Install dependencies
24
+ run: bundle install
25
+
26
+ - name: Run RSpec tests
27
+ run: bundle exec rspec
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## [1.0] - 2025-03-24
4
+ ### Added
5
+ - Support matching by service name (#40)
6
+
7
+ ## [1.0.1] - 2025-06-05
8
+ ### Added
9
+ - Allows forced outages to persist until explicitly ended, using `bundle exec rake breakers:end_forced_outage service="VAOS"`, for example.
data/README.md CHANGED
@@ -26,7 +26,7 @@ Or install it yourself as:
26
26
  ```ruby
27
27
  service = Breakers::Service.new(
28
28
  name: 'messaging',
29
- request_matcher: proc { |request_env| request_env.url.host =~ /.*messaging\.va\.gov/ }
29
+ request_matcher: proc { |breakers_service, request_env, request_service_name| request_env.url.host =~ /.*messaging\.va\.gov/ }
30
30
  )
31
31
 
32
32
  client = Breakers::Client.new(redis_connection: redis, services: [service])
@@ -57,7 +57,7 @@ are defined like this:
57
57
  ```ruby
58
58
  service = Breakers::Service.new(
59
59
  name: 'messaging',
60
- request_matcher: proc { |request_env| request_env.url.host =~ /.*messaging\.va\.gov/ },
60
+ request_matcher: proc { |breakers_service, request_env, request_service_name| breakers_service.name == request_service_name },
61
61
  seconds_before_retry: 60,
62
62
  error_threshold: 50
63
63
  )
@@ -142,17 +142,14 @@ It's ok for your plugin to implement only part of this interface.
142
142
 
143
143
  ### Forcing an Outage
144
144
 
145
- Some services will have status endpoints that you can use to check their availability, and you may want to create an outage based on that.
146
- Because this is a middleware, it doesn't have the ability to periodically check these endpoints, but you can add that type of check to your
147
- application and then force an outage in breakers:
148
-
149
- ```ruby
150
- service.begin_forced_outage!
151
- service.end_forced_outage!
145
+ You can test an outage by faking or forcing an outage using:
146
+ ```
147
+ Breakers::Outage#begin_forced_outage!
148
+ ```
149
+ Once an forced outage is started, you must manually stop it using:
150
+ ```
151
+ Breakers::Outage#end_forced_outage!
152
152
  ```
153
-
154
- Unlike with outages detected by the middleware, forced outages are not periodically tested to see if they have completed and must be
155
- manually ended with a call to `end_forced_outage!`.
156
153
 
157
154
  ### Changing the Outage Response
158
155
 
@@ -177,6 +174,10 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
177
174
 
178
175
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
179
176
 
177
+ **NOTE** If you have not previously signed in to Rubygems, you'll be prompted to:
178
+ * create and/or sign in to your account via your terminal
179
+ * (if you aren't already an owner) have an owner add you with `gem owner breakers --add <your_email@email.com>`
180
+
180
181
  ## Contributing
181
182
 
182
183
  Bug reports and pull requests are welcome on GitHub at https://github.com/department-of-veterans-affairs/breakers.
data/breakers.gemspec CHANGED
@@ -22,11 +22,12 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
+ spec.add_dependency 'base64', '~> 0.2'
25
26
  spec.add_dependency 'faraday', ['>= 1.2.0', '< 3.0']
26
27
  spec.add_dependency 'multi_json', '~> 1.0'
27
28
 
28
29
  spec.add_development_dependency 'bundler', '~> 2.0'
29
- spec.add_development_dependency 'byebug', '~> 9.0'
30
+ spec.add_development_dependency 'byebug', '~> 11.1'
30
31
  spec.add_development_dependency 'fakeredis', '~> 0.6.0'
31
32
  spec.add_development_dependency 'rake', '~> 12.0'
32
33
  spec.add_development_dependency 'rspec', '~> 3.0'
@@ -23,10 +23,11 @@ module Breakers
23
23
  # Given a request environment, return the service that should handle it.
24
24
  #
25
25
  # @param request_env [Faraday::Env] the request environment
26
+ # @param service_name [String] the service name
26
27
  # @return [Breakers::Service] the service object
27
- def service_for_request(request_env:)
28
+ def service_for_request(request_env:, service_name:)
28
29
  @services.find do |service|
29
- service.handles_request?(request_env: request_env)
30
+ service.handles_request?(request_env: request_env, service_name: service_name)
30
31
  end
31
32
  end
32
33
  end
@@ -33,8 +33,8 @@ module Breakers
33
33
  #
34
34
  # @param request_env [Faraday::Env] the request environment
35
35
  # @return [Boolean] should the service handle the request
36
- def handles_request?(request_env:)
37
- @configuration[:request_matcher].call(request_env)
36
+ def handles_request?(request_env:, service_name:)
37
+ @configuration[:request_matcher].call(self, request_env, service_name)
38
38
  end
39
39
 
40
40
  # Get the seconds before retry parameter
@@ -4,16 +4,21 @@ require 'multi_json'
4
4
  module Breakers
5
5
  # The faraday middleware
6
6
  class UptimeMiddleware < Faraday::Middleware
7
- def initialize(app)
7
+ def initialize(app, args = nil)
8
+ @service_name = args&.dig(:service_name)
8
9
  super(app)
9
10
  end
10
11
 
12
+ def service_name
13
+ @service_name
14
+ end
15
+
11
16
  def call(request_env)
12
17
  if Breakers.disabled?
13
18
  return @app.call(request_env)
14
19
  end
15
20
 
16
- service = Breakers.client.service_for_request(request_env: request_env)
21
+ service = Breakers.client.service_for_request(request_env: request_env, service_name: @service_name)
17
22
 
18
23
  if !service
19
24
  return @app.call(request_env)
@@ -21,13 +26,15 @@ module Breakers
21
26
 
22
27
  latest_outage = service.latest_outage
23
28
 
24
- if latest_outage && !latest_outage.ended?
25
- if latest_outage.ready_for_retest?(wait_seconds: service.seconds_before_retry)
29
+ if !latest_outage.nil? && !latest_outage&.ended?
30
+ if latest_outage.ready_for_retest?(wait_seconds: service.seconds_before_retry) && !latest_outage.forced?
31
+ # No outage detected, proceed with the request
26
32
  handle_request(service: service, request_env: request_env, current_outage: latest_outage)
27
33
  else
28
34
  outage_response(outage: latest_outage, service: service)
29
35
  end
30
36
  else
37
+ # No outage detected, proceed with the request
31
38
  handle_request(service: service, request_env: request_env)
32
39
  end
33
40
  end
@@ -40,9 +47,10 @@ module Breakers
40
47
  end
41
48
  if Breakers.outage_response[:type] == :status_code
42
49
  Faraday::Response.new.tap do |response|
50
+ forced = outage.forced? ? '[FORCED] ' : ''
43
51
  response.finish(
44
52
  status: Breakers.outage_response[:status_code],
45
- body: "Outage detected on #{service.name} beginning at #{outage.start_time.to_i}",
53
+ body: "#{forced}Outage detected on #{service.name} beginning at #{outage.start_time.to_i}",
46
54
  response_headers: {}
47
55
  )
48
56
  end
@@ -1,3 +1,3 @@
1
1
  module Breakers
2
- VERSION = '0.7.1'.freeze
2
+ VERSION = '1.0.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: breakers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aubrey Holland
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-08 00:00:00.000000000 Z
11
+ date: 2025-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base64
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: faraday
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -64,14 +78,14 @@ dependencies:
64
78
  requirements:
65
79
  - - "~>"
66
80
  - !ruby/object:Gem::Version
67
- version: '9.0'
81
+ version: '11.1'
68
82
  type: :development
69
83
  prerelease: false
70
84
  version_requirements: !ruby/object:Gem::Requirement
71
85
  requirements:
72
86
  - - "~>"
73
87
  - !ruby/object:Gem::Version
74
- version: '9.0'
88
+ version: '11.1'
75
89
  - !ruby/object:Gem::Dependency
76
90
  name: fakeredis
77
91
  requirement: !ruby/object:Gem::Requirement
@@ -179,10 +193,12 @@ extensions: []
179
193
  extra_rdoc_files: []
180
194
  files:
181
195
  - ".github/workflows/codeql.yml"
196
+ - ".github/workflows/rspec.yml"
182
197
  - ".gitignore"
183
198
  - ".rspec"
184
199
  - ".rubocop.yml"
185
200
  - ".travis.yml"
201
+ - CHANGELOG.md
186
202
  - CONTRIBUTING.md
187
203
  - Gemfile
188
204
  - LICENSE.md
@@ -217,7 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
233
  - !ruby/object:Gem::Version
218
234
  version: '0'
219
235
  requirements: []
220
- rubygems_version: 3.4.21
236
+ rubygems_version: 3.5.11
221
237
  signing_key:
222
238
  specification_version: 4
223
239
  summary: Handle outages to backend systems with a Faraday middleware