simple_circuit_breaker 0.1.0 → 0.2.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.
data/README.md CHANGED
@@ -4,6 +4,11 @@
4
4
 
5
5
  Simple Ruby implementation of the [Circuit Breaker design pattern][0].
6
6
 
7
+ This implementation aims to be as simple as possible. It does not have external
8
+ dependencies and only handles the core circuit breaker functionality. Wrapping
9
+ backend calls in timeouts and other exception handling is left to the user of
10
+ the library.
11
+
7
12
  ## Usage
8
13
 
9
14
  ```ruby
@@ -11,13 +16,26 @@ failure_threshold = 3 # Trip the circuit after 3 consecutive failures.
11
16
  retry_timeout = 10 # Retry on an open circuit after 10 seconds.
12
17
  circuit_breaker = SimpleCircuitBreaker.new(failure_threshold, retry_timeout)
13
18
 
19
+ # By default, all exceptions will trip the circuit.
14
20
  circuit_breaker.handle do
15
- FakeClient.new.request
21
+ FooClient.new.request
22
+ end
23
+
24
+ # Setting explicit exceptions that trip the circuit:
25
+ circuit_breaker.handle FooError, BarError do
26
+ FooClient.new.request
16
27
  end
17
28
  ```
18
29
 
19
- `SimpleCircuitBreaker#handle` raises a `SimpleCircuitBreaker::Error` when the
20
- circuit is open.
30
+ `SimpleCircuitBreaker#handle` raises a `SimpleCircuitBreaker::CircuitOpenError`
31
+ when the circuit is open. Otherwise, it re-raises any exceptions that occur in
32
+ the block.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ gem install simple_circuit_breaker
38
+ ```
21
39
 
22
40
  ## Testing
23
41
 
@@ -33,9 +51,16 @@ rake
33
51
 
34
52
  Julius Volz (julius@soundcloud.com), Tobias Schmidt (ts@soundcloud.com).
35
53
 
54
+ ## Alternatives
55
+
56
+ * [Circuit Breaker][2]: heavily customizable circuit handler
57
+ * [CircuitB][3]: supports keeping global circuit state in memcached
58
+
36
59
  ## Contributing
37
60
 
38
61
  Pull requests welcome!
39
62
 
40
63
  [0]: http://en.wikipedia.org/wiki/Circuit_breaker_design_pattern
41
64
  [1]: http://travis-ci.org/soundcloud/simple_circuit_breaker
65
+ [2]: https://github.com/wsargent/circuit_breaker
66
+ [3]: https://github.com/alg/circuit_b
@@ -1,7 +1,7 @@
1
1
  class SimpleCircuitBreaker
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
 
4
- class Error < StandardError
4
+ class CircuitOpenError < StandardError
5
5
  end
6
6
 
7
7
  attr_reader :failure_threshold, :retry_timeout
@@ -12,21 +12,23 @@ class SimpleCircuitBreaker
12
12
  reset!
13
13
  end
14
14
 
15
- def handle(&block)
15
+ def handle(*exceptions, &block)
16
16
  if tripped?
17
- raise Error, 'Circuit is open'
17
+ raise CircuitOpenError, 'Circuit is open'
18
18
  else
19
- execute(&block)
19
+ execute(exceptions, &block)
20
20
  end
21
21
  end
22
22
 
23
23
  protected
24
24
 
25
- def execute(&block)
25
+ def execute(exceptions, &block)
26
26
  begin
27
27
  yield.tap { success! }
28
- rescue Exception
29
- fail!
28
+ rescue Exception => exception
29
+ if exceptions.empty? || exceptions.include?(exception.class)
30
+ fail!
31
+ end
30
32
  raise
31
33
  end
32
34
  end
@@ -0,0 +1,18 @@
1
+ require './lib/simple_circuit_breaker'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'simple_circuit_breaker'
5
+ s.version = SimpleCircuitBreaker::VERSION
6
+ s.platform = Gem::Platform::RUBY
7
+ s.summary = 'Ruby Circuit Breaker implementation'
8
+ s.description = 'Simple Ruby implementation of the Circuit Breaker design pattern'
9
+ s.authors = ['Julius Volz', 'Tobias Schmidt']
10
+ s.email = 'julius@soundcloud.com ts@soundcloud.com'
11
+ s.homepage = 'http://github.com/soundcloud/simple_circuit_breaker'
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- test/*`.split("\n")
15
+ s.require_path = 'lib'
16
+
17
+ s.required_ruby_version = '>= 1.9'
18
+ end
@@ -32,7 +32,7 @@ describe SimpleCircuitBreaker do
32
32
  foo.must_equal 42
33
33
  end
34
34
 
35
- it 'opens after 3 consecutive failures' do
35
+ it 'opens after 3 consecutive failures with no explicit handled exceptions' do
36
36
  3.times do
37
37
  begin
38
38
  @breaker.handle { raise RuntimeError }
@@ -42,9 +42,36 @@ describe SimpleCircuitBreaker do
42
42
 
43
43
  Proc.new do
44
44
  @breaker.handle do
45
- raiseRuntimeError
45
+ raise RuntimeError
46
+ end
47
+ end.must_raise SimpleCircuitBreaker::CircuitOpenError
48
+ end
49
+
50
+ it 'opens after 3 consecutive failures for handled exception' do
51
+ 3.times do
52
+ begin
53
+ @breaker.handle(RuntimeError) { raise RuntimeError }
54
+ rescue RuntimeError
55
+ end
56
+ end
57
+
58
+ Proc.new do
59
+ @breaker.handle(RuntimeError) do
60
+ raise RuntimeError
61
+ end
62
+ end.must_raise SimpleCircuitBreaker::CircuitOpenError
63
+ end
64
+
65
+ it 'doesn\'t open after 3 consecutive failures for non-handled exception' do
66
+ class FooError < Exception
67
+ end
68
+
69
+ 4.times do
70
+ begin
71
+ @breaker.handle(FooError) { raise RuntimeError }
72
+ rescue RuntimeError
46
73
  end
47
- end.must_raise SimpleCircuitBreaker::Error
74
+ end
48
75
  end
49
76
  end
50
77
 
@@ -55,7 +82,7 @@ describe SimpleCircuitBreaker do
55
82
  @breaker.handle { raise RuntimeError } rescue nil
56
83
  end
57
84
 
58
- lambda { @breaker.handle {} }.must_raise SimpleCircuitBreaker::Error
85
+ lambda { @breaker.handle {} }.must_raise SimpleCircuitBreaker::CircuitOpenError
59
86
  end
60
87
 
61
88
  it 'closes after timeout and subsequent success' do
@@ -73,7 +100,7 @@ describe SimpleCircuitBreaker do
73
100
  end
74
101
  end.must_raise RuntimeError
75
102
 
76
- lambda { @breaker.handle {} }.must_raise SimpleCircuitBreaker::Error
103
+ lambda { @breaker.handle {} }.must_raise SimpleCircuitBreaker::CircuitOpenError
77
104
  end
78
105
  end
79
106
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_circuit_breaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-11-06 00:00:00.000000000 Z
13
+ date: 2012-11-07 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: Simple Ruby implementation of the Circuit Breaker design pattern
16
16
  email: julius@soundcloud.com ts@soundcloud.com
@@ -23,6 +23,7 @@ files:
23
23
  - README.md
24
24
  - Rakefile
25
25
  - lib/simple_circuit_breaker.rb
26
+ - simple_circuit_breaker.gemspec
26
27
  - test/simple_circuit_breaker_test.rb
27
28
  homepage: http://github.com/soundcloud/simple_circuit_breaker
28
29
  licenses: []