circuit_breakage 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b436b7a83a4e4470cf5bf209e276afa440eea28d
4
- data.tar.gz: bbf480897ba2a7db87096a939b505617bdaccb17
3
+ metadata.gz: 5aeb1835130f99946eddad6d46d8f01dd44a0fed
4
+ data.tar.gz: bdd92ef38ba1a708da8ac1cab7e9bb34c1b4fe8d
5
5
  SHA512:
6
- metadata.gz: dacf62b792eadf2d5c9589eb221a028f5e597a071362374357e200c5c0a41b33313243e99851fd9daa8d654aab52228d754350354d04e68afaaddf821e84de48
7
- data.tar.gz: 77455e880e39b757d046a11fb1e6cfe1394a88a947601a5b8adbbf8c55883b3dd5000b236485cdc5e696b7d971e507cff1a81b04e7935f7551e4b9f7e46121f6
6
+ metadata.gz: 73d6b93182c3bd07d75196ac21c3fb7a7ca47259183c57a512ae131821eddfb035abc65509cd3d62a9cb3deae30f148aa3d352d9a12c4362e9297ddf397bcc18
7
+ data.tar.gz: f7f86f802260ab60af42d2db4031ac62110ff8081bcc681e74be062a4a376af5e00a721e33df9cd50f3dd14d33472710d70cf7fe7bdaf864de72cc41a444892a
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # CircuitBreakage
2
2
 
3
- A simple Circuit Breaker implementation in Ruby with a timeout. A Circuit
4
- Breaker wraps a potentially troublesome block of code and will "trip" the
3
+ A simple circuit breaker implementation in Ruby with a timeout. A circuit
4
+ breaker wraps a potentially troublesome block of code and will "trip" the
5
5
  circuit (ie, stop trying to run the code) if it sees too many failures. After
6
6
  a configurable amount of time, the circuit breaker will retry.
7
7
 
@@ -24,9 +24,9 @@ breaker.timeout = 0.5 # 500 milliseconds allowed before auto-fail
24
24
 
25
25
  begin
26
26
  breaker.call(*some_args) # args are passed through to block
27
- rescue CircuitBreaker::CircuitOpen
27
+ rescue CircuitBreakage::CircuitOpen
28
28
  puts "Too many recent failures!"
29
- rescue CircuitBreaker::CircuitTimeout
29
+ rescue CircuitBreakage::CircuitTimeout
30
30
  puts "Operation timed out!"
31
31
  end
32
32
  ```
@@ -34,7 +34,7 @@ end
34
34
  A "failure" in this context means that the block either raised an exception or
35
35
  timed out.
36
36
 
37
- ### Redis-backed "Shared" Circuit Breakers
37
+ ### Redis-Backed "Shared" Circuit Breakers
38
38
 
39
39
  The unique feature of this particular Circuit Breaker gem is that it also
40
40
  supports shared state via Redis, using the SETNX and GETSET commands. This
@@ -1,3 +1,3 @@
1
- require "circuit_breakage/version"
2
- require "circuit_breakage/breaker"
3
- require "circuit_breakage/redis_backed_breaker"
1
+ require_relative "circuit_breakage/version"
2
+ require_relative "circuit_breakage/breaker"
3
+ require_relative "circuit_breakage/redis_backed_breaker"
@@ -9,7 +9,7 @@ module CircuitBreakage
9
9
  #
10
10
  class Breaker
11
11
  attr_accessor :failure_count, :last_failed, :state, :block
12
- attr_accessor :failure_threshold, :duration, :timeout
12
+ attr_accessor :failure_threshold, :duration, :timeout, :last_exception
13
13
 
14
14
  DEFAULT_FAILURE_THRESHOLD = 5 # Number of failures required to trip circuit
15
15
  DEFAULT_DURATION = 300 # Number of seconds the circuit stays tripped
@@ -54,7 +54,7 @@ module CircuitBreakage
54
54
 
55
55
  return ret_value
56
56
  rescue Exception => e
57
- handle_failure
57
+ handle_failure(e)
58
58
  end
59
59
 
60
60
  def time_to_retry?
@@ -66,12 +66,15 @@ module CircuitBreakage
66
66
  self.state = 'closed'
67
67
  end
68
68
 
69
- def handle_failure
69
+ def handle_failure(error)
70
70
  self.last_failed = Time.now
71
71
  self.failure_count += 1
72
72
  if self.failure_count >= self.failure_threshold
73
73
  self.state = 'open'
74
74
  end
75
+
76
+ self.last_exception = error
77
+ raise(error)
75
78
  end
76
79
  end
77
80
  end
@@ -1,3 +1,3 @@
1
1
  module CircuitBreakage
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
data/spec/breaker_spec.rb CHANGED
@@ -10,7 +10,7 @@ module CircuitBreakage
10
10
  end
11
11
 
12
12
  describe '#call' do
13
- subject { -> { breaker.call(arg) } }
13
+ subject { -> { breaker.call(arg) rescue nil} }
14
14
  let(:arg) { 'This is an argument.' }
15
15
 
16
16
  context 'when the circuit is closed' do
@@ -29,10 +29,15 @@ module CircuitBreakage
29
29
  end
30
30
 
31
31
  context 'and the call fails' do
32
- let(:block) { -> { raise 'some error' } }
32
+ let(:block) { ->(_) { raise 'some error' } }
33
33
 
34
34
  it { is_expected.to change { breaker.failure_count }.by(1) }
35
35
  it { is_expected.to change { breaker.last_failed } }
36
+ it { is_expected.to change { breaker.last_exception }.from(nil) }
37
+
38
+ it 'raises the exception that caused the failure' do
39
+ expect { breaker.call(arg) }.to raise_exception('some error')
40
+ end
36
41
 
37
42
  context 'and the failure count exceeds the failure threshold' do
38
43
  before { breaker.failure_count = breaker.failure_threshold }
@@ -46,7 +51,11 @@ module CircuitBreakage
46
51
  before { breaker.timeout = 0.1 }
47
52
 
48
53
  it 'counts as a failure' do
49
- expect { breaker.call(arg) }.to change { breaker.failure_count }.by(1)
54
+ expect { breaker.call(arg) rescue nil }.to change { breaker.failure_count }.by(1)
55
+ end
56
+
57
+ it 'raises CircuitBreakage::CircuitTimeout' do
58
+ expect { breaker.call(arg) }.to raise_exception(CircuitBreakage::CircuitTimeout)
50
59
  end
51
60
  end
52
61
  end
@@ -57,7 +66,9 @@ module CircuitBreakage
57
66
  context 'before the retry_time' do
58
67
  before { breaker.last_failed = Time.now - breaker.duration + 30 }
59
68
 
60
- it { is_expected.to raise_error(CircuitOpen) }
69
+ it 'raises CircuitBreakage::CircuitOpen' do
70
+ expect { breaker.call(arg) }.to raise_error(CircuitOpen)
71
+ end
61
72
  end
62
73
 
63
74
  context 'after the retry time' do
@@ -9,7 +9,7 @@ module CircuitBreakage
9
9
  let(:block) { ->(x) { return x } }
10
10
 
11
11
  describe '#call' do
12
- subject { -> { breaker.call(arg) } }
12
+ subject { -> { breaker.call(arg) rescue nil } }
13
13
  let(:arg) { 'This is an argument.' }
14
14
 
15
15
  context 'when the circuit is closed' do
@@ -28,7 +28,7 @@ module CircuitBreakage
28
28
  end
29
29
 
30
30
  context 'and the call fails' do
31
- let(:block) { -> { raise 'some error' } }
31
+ let(:block) { ->(_) { raise 'some error' } }
32
32
 
33
33
  it { is_expected.to change { breaker.failure_count }.by(1) }
34
34
  it { is_expected.to change { breaker.last_failed } }
@@ -45,7 +45,7 @@ module CircuitBreakage
45
45
  before { breaker.timeout = 0.1 }
46
46
 
47
47
  it 'counts as a failure' do
48
- expect { breaker.call(arg) }.to change { breaker.failure_count }.by(1)
48
+ expect { breaker.call(arg) rescue nil }.to change { breaker.failure_count }.by(1)
49
49
  end
50
50
  end
51
51
  end
@@ -56,7 +56,9 @@ module CircuitBreakage
56
56
  context 'before the retry_time' do
57
57
  before { breaker.last_failed = Time.now - breaker.duration + 30 }
58
58
 
59
- it { is_expected.to raise_error(CircuitOpen) }
59
+ it 'raises CircuitBreakage::CircuitOpen' do
60
+ expect { breaker.call(arg) }.to raise_error(CircuitOpen)
61
+ end
60
62
  end
61
63
 
62
64
  context 'after the retry time' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: circuit_breakage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Hyland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-16 00:00:00.000000000 Z
11
+ date: 2015-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler