faulty 0.8.6 → 0.8.7

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.
@@ -9,7 +9,7 @@ class Faulty
9
9
  # cascading failures in your application when evaluating circuits. Always
10
10
  # wrap this backend with a {FaultTolerantProxy} to limit the effect of
11
11
  # these types of events.
12
- class Redis # rubocop:disable Metrics/ClassLength
12
+ class Redis
13
13
  # Separates the time/status for history entry strings
14
14
  ENTRY_SEPARATOR = ':'
15
15
 
@@ -95,7 +95,7 @@ class Faulty
95
95
  # @param (see Interface#get_options)
96
96
  # @return (see Interface#get_options)
97
97
  def get_options(circuit)
98
- json = redis { |r| r.get(options_key(circuit)) }
98
+ json = redis { |r| r.get(options_key(circuit.name)) }
99
99
  return if json.nil?
100
100
 
101
101
  JSON.parse(json, symbolize_names: true)
@@ -110,7 +110,7 @@ class Faulty
110
110
  # @return (see Interface#set_options)
111
111
  def set_options(circuit, stored_options)
112
112
  redis do |r|
113
- r.set(options_key(circuit), JSON.dump(stored_options), ex: options.circuit_ttl)
113
+ r.set(options_key(circuit.name), JSON.dump(stored_options), ex: options.circuit_ttl)
114
114
  end
115
115
  end
116
116
 
@@ -120,7 +120,7 @@ class Faulty
120
120
  # @param (see Interface#entry)
121
121
  # @return (see Interface#entry)
122
122
  def entry(circuit, time, success, status)
123
- key = entries_key(circuit)
123
+ key = entries_key(circuit.name)
124
124
  result = pipe do |r|
125
125
  r.sadd(list_key, circuit.name)
126
126
  r.expire(list_key, options.circuit_ttl + options.list_granularity) if options.circuit_ttl
@@ -139,11 +139,11 @@ class Faulty
139
139
  # @param (see Interface#open)
140
140
  # @return (see Interface#open)
141
141
  def open(circuit, opened_at)
142
- key = state_key(circuit)
142
+ key = state_key(circuit.name)
143
143
  ex = options.circuit_ttl
144
144
  result = watch_exec(key, ['closed', nil]) do |m|
145
145
  m.set(key, 'open', ex: ex)
146
- m.set(opened_at_key(circuit), opened_at, ex: ex)
146
+ m.set(opened_at_key(circuit.name), opened_at, ex: ex)
147
147
  end
148
148
 
149
149
  result && result[0] == 'OK'
@@ -155,7 +155,7 @@ class Faulty
155
155
  # @param (see Interface#reopen)
156
156
  # @return (see Interface#reopen)
157
157
  def reopen(circuit, opened_at, previous_opened_at)
158
- key = opened_at_key(circuit)
158
+ key = opened_at_key(circuit.name)
159
159
  result = watch_exec(key, [previous_opened_at.to_s]) do |m|
160
160
  m.set(key, opened_at, ex: options.circuit_ttl)
161
161
  end
@@ -169,11 +169,11 @@ class Faulty
169
169
  # @param (see Interface#close)
170
170
  # @return (see Interface#close)
171
171
  def close(circuit)
172
- key = state_key(circuit)
172
+ key = state_key(circuit.name)
173
173
  ex = options.circuit_ttl
174
174
  result = watch_exec(key, ['open']) do |m|
175
175
  m.set(key, 'closed', ex: ex)
176
- m.del(entries_key(circuit))
176
+ m.del(entries_key(circuit.name))
177
177
  end
178
178
 
179
179
  result && result[0] == 'OK'
@@ -187,7 +187,7 @@ class Faulty
187
187
  # @param (see Interface#lock)
188
188
  # @return (see Interface#lock)
189
189
  def lock(circuit, state)
190
- redis { |r| r.set(lock_key(circuit), state) }
190
+ redis { |r| r.set(lock_key(circuit.name), state) }
191
191
  end
192
192
 
193
193
  # Unlock a circuit
@@ -196,7 +196,7 @@ class Faulty
196
196
  # @param (see Interface#unlock)
197
197
  # @return (see Interface#unlock)
198
198
  def unlock(circuit)
199
- redis { |r| r.del(lock_key(circuit)) }
199
+ redis { |r| r.del(lock_key(circuit.name)) }
200
200
  end
201
201
 
202
202
  # Reset a circuit
@@ -205,14 +205,15 @@ class Faulty
205
205
  # @param (see Interface#reset)
206
206
  # @return (see Interface#reset)
207
207
  def reset(circuit)
208
+ name = circuit.is_a?(Circuit) ? circuit.name : circuit
208
209
  pipe do |r|
209
210
  r.del(
210
- entries_key(circuit),
211
- opened_at_key(circuit),
212
- lock_key(circuit),
213
- options_key(circuit)
211
+ entries_key(name),
212
+ opened_at_key(name),
213
+ lock_key(name),
214
+ options_key(name)
214
215
  )
215
- r.set(state_key(circuit), 'closed', ex: options.circuit_ttl)
216
+ r.set(state_key(name), 'closed', ex: options.circuit_ttl)
216
217
  end
217
218
  end
218
219
 
@@ -224,10 +225,10 @@ class Faulty
224
225
  def status(circuit)
225
226
  futures = {}
226
227
  pipe do |r|
227
- futures[:state] = r.get(state_key(circuit))
228
- futures[:lock] = r.get(lock_key(circuit))
229
- futures[:opened_at] = r.get(opened_at_key(circuit))
230
- futures[:entries] = r.lrange(entries_key(circuit), 0, -1)
228
+ futures[:state] = r.get(state_key(circuit.name))
229
+ futures[:lock] = r.get(lock_key(circuit.name))
230
+ futures[:opened_at] = r.get(opened_at_key(circuit.name))
231
+ futures[:entries] = r.lrange(entries_key(circuit.name), 0, -1)
231
232
  end
232
233
 
233
234
  state = futures[:state].value&.to_sym || :closed
@@ -249,7 +250,7 @@ class Faulty
249
250
  # @param (see Interface#history)
250
251
  # @return (see Interface#history)
251
252
  def history(circuit)
252
- entries = redis { |r| r.lrange(entries_key(circuit), 0, -1) }
253
+ entries = redis { |r| r.lrange(entries_key(circuit.name), 0, -1) }
253
254
  map_entries(entries).reverse
254
255
  end
255
256
 
@@ -260,6 +261,21 @@ class Faulty
260
261
  redis { |r| r.sunion(*all_list_keys) }
261
262
  end
262
263
 
264
+ # Reset all circuits
265
+ #
266
+ # This does not empty the list of circuits as returned by {#list}. This is
267
+ # because that would be a thread-usafe operation that could result in
268
+ # circuits not being in the list.
269
+ #
270
+ # This implmenentation resets circuits individually, and will be very
271
+ # slow for large numbers of circuits. It should not be used in production
272
+ # code.
273
+ #
274
+ # @return [void]
275
+ def clear
276
+ list.each { |c| reset(c) }
277
+ end
278
+
263
279
  # Redis storage is not fault-tolerant
264
280
  #
265
281
  # @return [true]
@@ -276,33 +292,33 @@ class Faulty
276
292
  [options.key_prefix, *parts].join(options.key_separator)
277
293
  end
278
294
 
279
- def ckey(circuit, *parts)
280
- key('circuit', circuit.name, *parts)
295
+ def ckey(circuit_name, *parts)
296
+ key('circuit', circuit_name, *parts)
281
297
  end
282
298
 
283
299
  # @return [String] The key for circuit options
284
- def options_key(circuit)
285
- ckey(circuit, 'options')
300
+ def options_key(circuit_name)
301
+ ckey(circuit_name, 'options')
286
302
  end
287
303
 
288
304
  # @return [String] The key for circuit state
289
- def state_key(circuit)
290
- ckey(circuit, 'state')
305
+ def state_key(circuit_name)
306
+ ckey(circuit_name, 'state')
291
307
  end
292
308
 
293
309
  # @return [String] The key for circuit run history entries
294
- def entries_key(circuit)
295
- ckey(circuit, 'entries')
310
+ def entries_key(circuit_name)
311
+ ckey(circuit_name, 'entries')
296
312
  end
297
313
 
298
314
  # @return [String] The key for circuit locks
299
- def lock_key(circuit)
300
- ckey(circuit, 'lock')
315
+ def lock_key(circuit_name)
316
+ ckey(circuit_name, 'lock')
301
317
  end
302
318
 
303
319
  # @return [String] The key for circuit opened_at
304
- def opened_at_key(circuit)
305
- ckey(circuit, 'opened_at')
320
+ def opened_at_key(circuit_name)
321
+ ckey(circuit_name, 'opened_at')
306
322
  end
307
323
 
308
324
  # Get the current key to add circuit names to
@@ -354,13 +370,11 @@ class Faulty
354
370
  # the watch succeeds and the comparison passes
355
371
  # @return [Array] An array of Redis results from the commands executed
356
372
  # inside the block
357
- def watch_exec(key, old)
373
+ def watch_exec(key, old, &block)
358
374
  redis do |r|
359
375
  r.watch(key) do
360
376
  if old.include?(r.get(key))
361
- r.multi do |m|
362
- yield m
363
- end
377
+ r.multi(&block)
364
378
  else
365
379
  r.unwatch
366
380
  nil
@@ -373,9 +387,9 @@ class Faulty
373
387
  #
374
388
  # @yield [Redis] Yields the connection to the block
375
389
  # @return The value returned from the block
376
- def redis
390
+ def redis(&block)
377
391
  if options.client.respond_to?(:with)
378
- options.client.with { |redis| yield redis }
392
+ options.client.with(&block)
379
393
  else
380
394
  yield options.client
381
395
  end
@@ -385,8 +399,8 @@ class Faulty
385
399
  #
386
400
  # @yield [Redis::Pipeline] Yields the connection to the block
387
401
  # @return [void]
388
- def pipe
389
- redis { |r| r.pipelined { |p| yield p } }
402
+ def pipe(&block)
403
+ redis { |r| r.pipelined(&block) }
390
404
  end
391
405
 
392
406
  # Map raw Redis history entries to Faulty format
@@ -435,7 +449,7 @@ class Faulty
435
449
  end
436
450
 
437
451
  def check_pool_options!
438
- if options.client.class.name == 'ConnectionPool'
452
+ if options.client.instance_of?(ConnectionPool)
439
453
  timeout = options.client.instance_variable_get(:@timeout)
440
454
  warn(<<~MSG) if timeout > 2
441
455
  Faulty recommends setting ConnectionPool timeouts <= 2 to prevent
@@ -3,6 +3,6 @@
3
3
  class Faulty
4
4
  # The current Faulty version
5
5
  def self.version
6
- Gem::Version.new('0.8.6')
6
+ Gem::Version.new('0.8.7')
7
7
  end
8
8
  end
data/lib/faulty.rb CHANGED
@@ -116,6 +116,7 @@ class Faulty
116
116
 
117
117
  # Get a list of all circuit names for the default instance
118
118
  #
119
+ # @see #list_circuits
119
120
  # @return [Array<String>] The circuit names
120
121
  def list_circuits
121
122
  options.storage.list
@@ -157,6 +158,14 @@ class Faulty
157
158
  def disabled?
158
159
  @disabled == true
159
160
  end
161
+
162
+ # Reset all circuits for the default instance
163
+ #
164
+ # @see #clear
165
+ # @return [void]
166
+ def clear!
167
+ default.clear
168
+ end
160
169
  end
161
170
 
162
171
  attr_reader :options
@@ -255,6 +264,20 @@ class Faulty
255
264
  options.storage.list
256
265
  end
257
266
 
267
+ # Reset all circuits
268
+ #
269
+ # Intended for use in tests. This can be expensive and is not appropriate
270
+ # to call in production code
271
+ #
272
+ # See the documentation for your chosen backend for specific semantics and
273
+ # safety concerns. For example, the Redis backend resets all circuits, but
274
+ # it does not clear the circuit list to maintain thread-safety.
275
+ #
276
+ # @return [void]
277
+ def clear!
278
+ options.storage.clear
279
+ end
280
+
258
281
  private
259
282
 
260
283
  # Get circuit options from the {Faulty} options
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faulty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.6
4
+ version: 0.8.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Howard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-24 00:00:00.000000000 Z
11
+ date: 2022-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -80,34 +80,6 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.8'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - '='
88
- - !ruby/object:Gem::Version
89
- version: 0.81.0
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - '='
95
- - !ruby/object:Gem::Version
96
- version: 0.81.0
97
- - !ruby/object:Gem::Dependency
98
- name: rubocop-rspec
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - '='
102
- - !ruby/object:Gem::Version
103
- version: 1.38.1
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - '='
109
- - !ruby/object:Gem::Version
110
- version: 1.38.1
111
83
  - !ruby/object:Gem::Dependency
112
84
  name: timecop
113
85
  requirement: !ruby/object:Gem::Requirement
@@ -129,24 +101,10 @@ executables: []
129
101
  extensions: []
130
102
  extra_rdoc_files: []
131
103
  files:
132
- - ".github/workflows/ci.yml"
133
- - ".gitignore"
134
- - ".rspec"
135
- - ".rubocop.yml"
136
104
  - ".yardopts"
137
105
  - CHANGELOG.md
138
- - Gemfile
139
106
  - LICENSE.txt
140
107
  - README.md
141
- - bin/benchmark
142
- - bin/check-version
143
- - bin/console
144
- - bin/rspec
145
- - bin/rubocop
146
- - bin/yard
147
- - bin/yardoc
148
- - bin/yri
149
- - faulty.gemspec
150
108
  - lib/faulty.rb
151
109
  - lib/faulty/cache.rb
152
110
  - lib/faulty/cache/auto_wire.rb
@@ -189,7 +147,10 @@ files:
189
147
  homepage: https://github.com/ParentSquare/faulty
190
148
  licenses:
191
149
  - MIT
192
- metadata: {}
150
+ metadata:
151
+ rubygems_mfa_required: 'true'
152
+ changelog_uri: https://github.com/ParentSquare/faulty/blob/master/CHANGELOG.md
153
+ documentation_uri: https://www.rubydoc.info/gems/faulty/0.8.7
193
154
  post_install_message:
194
155
  rdoc_options: []
195
156
  require_paths:
@@ -1,66 +0,0 @@
1
- ---
2
- name: CI
3
- on:
4
- push:
5
- tags: ['v*']
6
- branches: [master]
7
- pull_request:
8
- branches: ['**']
9
- jobs:
10
- test:
11
- runs-on: ubuntu-latest
12
- strategy:
13
- fail-fast: false
14
- matrix:
15
- redis: [4]
16
- ruby: [2.3, 2.4, 2.5, 2.6, 2.7, 3.0, jruby-9.2.10, truffleruby-20.2.0]
17
- include:
18
- - redis: 3
19
- ruby: 2.7
20
- services:
21
- redis:
22
- image: redis
23
- ports:
24
- - 6379:6379
25
- elasticsearch:
26
- image: elasticsearch:7.13.4
27
- ports:
28
- - 9200:9200
29
- options: -e="discovery.type=single-node" --health-cmd="curl http://localhost:9200/_cluster/health" --health-interval=3s --health-timeout=5s --health-retries=20
30
- steps:
31
- - uses: actions/checkout@v2
32
- - uses: ruby/setup-ruby@v1
33
- env:
34
- REDIS_VERSION: ${{ matrix.redis }}
35
- with:
36
- ruby-version: ${{ matrix.ruby }}
37
- bundler-cache: true
38
- - run: bundle exec rubocop
39
- if: matrix.ruby == '2.7'
40
- - run: bin/yardoc --fail-on-warning
41
- if: matrix.ruby == '2.7'
42
- - run: bin/check-version
43
- - name: start MySQL
44
- run: sudo /etc/init.d/mysql start
45
- - run: bundle exec rspec --format doc
46
- env:
47
- MYSQL_USER: root
48
- MYSQL_PASSWORD: root
49
- - name: Run codacy-coverage-reporter
50
- env:
51
- CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
52
- if: matrix.ruby == '2.7' && env.CODACY_PROJECT_TOKEN
53
- uses: codacy/codacy-coverage-reporter-action@master
54
- with:
55
- project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
56
- coverage-reports: coverage/lcov/faulty.lcov
57
-
58
- release:
59
- needs: test
60
- if: startsWith(github.ref, 'refs/tags/v')
61
- runs-on: ubuntu-latest
62
- steps:
63
- - uses: actions/checkout@v2
64
- - uses: dawidd6/action-publish-gem@v1
65
- with:
66
- api_key: ${{secrets.RUBYGEMS_API_KEY}}
data/.gitignore DELETED
@@ -1,11 +0,0 @@
1
- /.bundle/
2
- /Gemfile.lock
3
- /vendor/
4
- /.ruby-version
5
- /*.gem
6
-
7
- /coverage/
8
- /doc/
9
- /.yardoc/
10
-
11
- .byebug_history
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,97 +0,0 @@
1
- ---
2
- require:
3
- - rubocop-rspec
4
-
5
- AllCops:
6
- TargetRubyVersion: 2.3
7
-
8
- Layout/ArgumentAlignment:
9
- EnforcedStyle: with_fixed_indentation
10
-
11
- Layout/CaseIndentation:
12
- EnforcedStyle: end
13
-
14
- Layout/ParameterAlignment:
15
- EnforcedStyle: with_fixed_indentation
16
-
17
- Layout/EndAlignment:
18
- EnforcedStyleAlignWith: start_of_line
19
-
20
- Layout/FirstArgumentIndentation:
21
- EnforcedStyle: consistent
22
-
23
- Layout/FirstArrayElementIndentation:
24
- EnforcedStyle: consistent
25
-
26
- Layout/FirstHashElementIndentation:
27
- EnforcedStyle: consistent
28
-
29
- Layout/LineLength:
30
- Max: 120
31
-
32
- Layout/MultilineMethodCallIndentation:
33
- EnforcedStyle: indented
34
-
35
- Layout/RescueEnsureAlignment:
36
- Enabled: false
37
-
38
- Lint/RaiseException:
39
- Enabled: true
40
-
41
- Lint/StructNewOverride:
42
- Enabled: true
43
-
44
- RSpec/ExampleLength:
45
- Enabled: false
46
-
47
- RSpec/FilePath:
48
- Enabled: false
49
-
50
- RSpec/NamedSubject:
51
- Enabled: false
52
-
53
- RSpec/MessageSpies:
54
- Enabled: false
55
-
56
- RSpec/MultipleExpectations:
57
- Enabled: false
58
-
59
- RSpec/SubjectStub:
60
- Enabled: false
61
-
62
- Metrics/AbcSize:
63
- Max: 35
64
-
65
- Metrics/BlockLength:
66
- Enabled: false
67
-
68
- Metrics/MethodLength:
69
- Max: 30
70
-
71
- Naming/MethodParameterName:
72
- MinNameLength: 1
73
-
74
- Style/Documentation:
75
- Enabled: false
76
-
77
- Style/EmptyMethod:
78
- EnforcedStyle: expanded
79
-
80
- Style/FrozenStringLiteralComment:
81
- Enabled: true
82
- EnforcedStyle: always
83
-
84
- Style/GuardClause:
85
- Enabled: false
86
-
87
- Style/HashEachMethods:
88
- Enabled: true
89
-
90
- Style/HashTransformKeys:
91
- Enabled: false
92
-
93
- Style/HashTransformValues:
94
- Enabled: false
95
-
96
- Style/IfUnlessModifier:
97
- Enabled: false
data/Gemfile DELETED
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- gemspec
6
-
7
- # We add non-essential gems like debugging tools and CI dependencies
8
- # here. This also allows us to use conditional dependencies that depend on the
9
- # platform
10
-
11
- not_jruby = %i[ruby mingw x64_mingw].freeze
12
-
13
- gem 'activesupport', '>= 4.2'
14
- gem 'bundler', '>= 1.17', '< 3'
15
- gem 'byebug', platforms: not_jruby
16
- # Open source licensed elasticsearch
17
- gem 'elasticsearch', '> 7', '< 7.14'
18
- gem 'honeybadger', '>= 2.0'
19
- gem 'irb', '~> 1.0'
20
- # Minimum of 0.5.0 for specific error classes
21
- gem 'mysql2', '>= 0.5.0', platforms: not_jruby
22
- gem 'redcarpet', '~> 3.5', platforms: not_jruby
23
- gem 'rspec_junit_formatter', '~> 0.4'
24
- gem 'simplecov', '>= 0.17.1'
25
- # 0.8 is incompatible with simplecov < 0.18
26
- # https://github.com/fortissimo1997/simplecov-lcov/pull/25
27
- gem 'simplecov-lcov', '~> 0.7', '< 0.8'
28
- gem 'yard', '~> 0.9.25', platforms: not_jruby
29
-
30
- if ENV['REDIS_VERSION']
31
- gem 'redis', "~> #{ENV['REDIS_VERSION']}"
32
- end
data/bin/benchmark DELETED
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'bundler/setup'
5
- require 'benchmark'
6
- require 'faulty'
7
- require 'redis'
8
- require 'json'
9
-
10
- n = 100_000
11
- width = 25
12
- puts "In memory circuits x#{n}"
13
- Benchmark.bm(width) do |b|
14
- in_memory = Faulty.new(listeners: [])
15
- b.report('memory storage') do
16
- n.times { in_memory.circuit(:memory).run { true } }
17
- end
18
-
19
- b.report('memory storage failures') do
20
- n.times do
21
- begin
22
- in_memory.circuit(:memory_fail, sample_threshold: n + 1).run { raise 'fail' }
23
- rescue StandardError
24
- # Expected to raise here
25
- end
26
- end
27
- end
28
-
29
- in_memory_large = Faulty.new(listeners: [], storage: Faulty::Storage::Memory.new(max_sample_size: 1000))
30
- b.report('large memory storage') do
31
- n.times { in_memory_large.circuit(:memory_large).run { true } }
32
- end
33
- end
34
-
35
- n = 1000
36
- puts "\n\Redis circuits x#{n}"
37
- Benchmark.bm(width) do |b|
38
- redis = Faulty.new(listeners: [], storage: Faulty::Storage::Redis.new)
39
- b.report('redis storage') do
40
- n.times { redis.circuit(:memory).run { true } }
41
- end
42
-
43
- b.report('redis storage failures') do
44
- n.times do
45
- begin
46
- redis.circuit(:memory_fail, sample_threshold: n + 1).run { raise 'fail' }
47
- rescue StandardError
48
- # Expected to raise here
49
- end
50
- end
51
- end
52
-
53
- redis_large = Faulty.new(listeners: [], storage: Faulty::Storage::Redis.new(max_sample_size: 1000))
54
- b.report('large redis storage') do
55
- n.times { redis_large.circuit(:memory).run { true } }
56
- end
57
- end
58
-
59
- n = 1_000_000
60
- puts "\n\nExtra x#{n}"
61
- Benchmark.bm(width) do |b|
62
- in_memory = Faulty.new(listeners: [])
63
-
64
- log_listener = Faulty::Events::LogListener.new(Logger.new(File::NULL))
65
- log_circuit = in_memory.circuit(:log_listener)
66
- log_status = log_circuit.status
67
- b.report('log listener success') do
68
- n.times { log_listener.handle(:circuit_success, circuit: log_circuit, status: log_status) }
69
- end
70
-
71
- log_error = StandardError.new('test error')
72
- b.report('log listener failure') do
73
- n.times { log_listener.handle(:circuit_failure, error: log_error, circuit: log_circuit, status: log_status) }
74
- end
75
- end
data/bin/check-version DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env sh
2
-
3
- set -e
4
-
5
- tag="$(git describe --abbrev=0 2>/dev/null || echo)"
6
- echo "Tag: ${tag}"
7
- tag="${tag#v}"
8
- echo "Git Version: ${tag}"
9
- [ "$tag" = '' ] && exit 0
10
- gem_version="$(ruby -r ./lib/faulty/version -e "puts Faulty.version" | tail -n1)"
11
- echo "Gem Version: ${gem_version}"
12
-
13
- tag_gt_version="$(ruby -r ./lib/faulty/version -e "puts Faulty.version >= Gem::Version.new('${tag}')" | tail -n1)"
14
- test "$tag_gt_version" = true