circuitbox 0.8.0 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a837fae089566b81f6ccd58a7b89b4c119f122d4
4
- data.tar.gz: e78c6f2bf1437d2e5cd4495d106b8c822dbbd896
3
+ metadata.gz: 87808cd77975fc82ac067b5c0c82f72f993f6b77
4
+ data.tar.gz: 74889c759914d18561ec967cd77edde519bd6d5d
5
5
  SHA512:
6
- metadata.gz: bcd00fa6cb16dbb3a7ea62d912049a1b6c1d676b4c484f1e42e8ae65b060b215e673e3ec0ccb0ff2f15cce6ceff60c0b62e0ab1bc752a4b9d65674a74edf6afe
7
- data.tar.gz: f066a4d85503ed0db075a0df074f9eacd5dd9740cc2a5af5fbb289c07b48a287cea07a64c75eb3ced6b37f06a410608f657a24ce9688cf49c0fae31171b9bb9f
6
+ metadata.gz: 427a52c594b433cc8a506ebe995d56c64b7f1174766c74ce43f476cbf4f848656c2e9c9f6867a8cc31fcadecd92c64a7fcff4db865e7e4cca2c0605e18f6fc0b
7
+ data.tar.gz: 6236374797da10131120158b8c2c65f2cff3b4654f3b3ca24a0c85a27f02a6ccb20025babab8c412f6ea82d8457027d600544b9cd857c16fdea2a4636cfb38f8
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .idea
data/README.md CHANGED
@@ -32,6 +32,17 @@ class ExampleServiceClient
32
32
  end
33
33
  ```
34
34
 
35
+ Using the `run!` method will throw an exception when the circuit is open or the underlying service fails.
36
+
37
+ ```ruby
38
+ def http_get
39
+ circuit.run! do
40
+ Zephyr.new("http://example.com").get(200, 1000, "/api/messages")
41
+ end
42
+ end
43
+ ```
44
+
45
+
35
46
  ## Configuration
36
47
 
37
48
  ```ruby
@@ -188,7 +199,7 @@ c.use Circuitbox::FaradayMiddleware, circuit_breaker_options: {}
188
199
  ## TODO
189
200
  * ~~Fix Faraday integration to return a Faraday response object~~
190
201
  * Split stats into it's own repository
191
- * Circuit Breaker should raise an exception by default instead of returning nil
202
+ * ~~Circuit Breaker should raise an exception by default instead of returning nil~~
192
203
  * Refactor to use single state variable
193
204
  * Fix the partition hack
194
205
  * Integrate with Breakerbox/Hystrix
data/lib/circuitbox.rb CHANGED
@@ -3,12 +3,16 @@ require 'active_support'
3
3
  require 'logger'
4
4
  require 'timeout'
5
5
 
6
- require "circuitbox/version"
6
+ require 'circuitbox/version'
7
7
  require 'circuitbox/memcache_store'
8
8
  require 'circuitbox/railtie' if defined?(Rails)
9
9
  require 'circuitbox/circuit_breaker'
10
10
  require 'circuitbox/notifier'
11
11
 
12
+ require 'circuitbox/errors/error'
13
+ require 'circuitbox/errors/open_circuit_error'
14
+ require 'circuitbox/errors/service_failure_error'
15
+
12
16
  class Circuitbox
13
17
  attr_accessor :circuits, :circuit_store, :stat_store
14
18
  cattr_accessor :configure
@@ -67,4 +71,4 @@ class Circuitbox
67
71
  uri = URI(param.to_s)
68
72
  uri.host.present? ? uri.host : param.to_s
69
73
  end
70
- end
74
+ end
@@ -41,14 +41,14 @@ class Circuitbox
41
41
  value.is_a?(Proc) ? value.call : value
42
42
  end
43
43
 
44
- def run(run_options = {}, &block)
44
+ def run!(run_options = {})
45
45
  @partition = run_options.delete(:partition) # sorry for this hack.
46
46
  cache_key = run_options.delete(:storage_key)
47
47
 
48
48
  if open?
49
49
  logger.debug "[CIRCUIT] open: skipping #{service}"
50
- response = nil
51
50
  open! unless open_flag?
51
+ raise Circuitbox::OpenCircuitError.new(service)
52
52
  else
53
53
  close! if was_open?
54
54
  logger.debug "[CIRCUIT] closed: querying #{service}"
@@ -67,14 +67,26 @@ class Circuitbox
67
67
  rescue *exceptions => exception
68
68
  logger.debug "[CIRCUIT] closed: detected #{service} failure"
69
69
  failure!
70
- response = cache_key ? get_cached_response(cache_key) : nil
71
70
  open! if half_open?
71
+ if cache_key
72
+ response = get_cached_response(cache_key)
73
+ else
74
+ raise Circuitbox::ServiceFailureError.new(service, exception)
75
+ end
72
76
  end
73
77
  end
74
78
 
75
79
  return response
76
80
  end
77
81
 
82
+ def run(run_options = {})
83
+ begin
84
+ run!(run_options, &Proc.new)
85
+ rescue Circuitbox::Error
86
+ nil
87
+ end
88
+ end
89
+
78
90
  def open?
79
91
  if open_flag?
80
92
  true
@@ -0,0 +1,4 @@
1
+ class Circuitbox
2
+ class Error < StandardError
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ class Circuitbox
2
+ class OpenCircuitError < Circuitbox::Error
3
+ attr_reader :service
4
+
5
+ def initialize(service)
6
+ @service = service
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ class Circuitbox
2
+ class ServiceFailureError < Circuitbox::Error
3
+ attr_reader :service, :original
4
+
5
+ def initialize(service, exception)
6
+ @service = service
7
+ @original = exception
8
+ end
9
+
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  class Circuitbox
2
- VERSION='0.8.0'
2
+ VERSION='0.9.0'
3
3
  end
@@ -133,6 +133,23 @@ class CircuitBreakerTest < Minitest::Test
133
133
 
134
134
  end
135
135
 
136
+ describe 'exceptions' do
137
+ before do
138
+ Circuitbox::CircuitBreaker.reset
139
+ @circuit = Circuitbox::CircuitBreaker.new(:yammer, exceptions: [SomeOtherError])
140
+ end
141
+
142
+ it 'raises exception when circuit is open' do
143
+ @circuit.stubs(open_flag?: true)
144
+ -> { @circuit.run! {} }.must_raise Circuitbox::OpenCircuitError
145
+ end
146
+
147
+ it 'raises exception when service fails' do
148
+ err = -> { @circuit.run! { raise SomeOtherError } }.must_raise Circuitbox::ServiceFailureError
149
+ err.original.must_be_instance_of SomeOtherError
150
+ end
151
+ end
152
+
136
153
  describe 'closing the circuit after sleep' do
137
154
  class GodTime < SimpleDelegator
138
155
  def now
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: circuitbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fahim Ferdous
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-17 00:00:00.000000000 Z
11
+ date: 2015-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -209,6 +209,9 @@ files:
209
209
  - circuitbox.gemspec
210
210
  - lib/circuitbox.rb
211
211
  - lib/circuitbox/circuit_breaker.rb
212
+ - lib/circuitbox/errors/error.rb
213
+ - lib/circuitbox/errors/open_circuit_error.rb
214
+ - lib/circuitbox/errors/service_failure_error.rb
212
215
  - lib/circuitbox/faraday_middleware.rb
213
216
  - lib/circuitbox/memcache_store.rb
214
217
  - lib/circuitbox/notifier.rb
@@ -242,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
242
245
  version: '0'
243
246
  requirements: []
244
247
  rubyforge_project:
245
- rubygems_version: 2.2.2
248
+ rubygems_version: 2.4.5
246
249
  signing_key:
247
250
  specification_version: 4
248
251
  summary: A robust circuit breaker that manages failing external services.