circuitbox 2.0.0.pre3 → 2.0.0.pre4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +3 -75
- data/lib/circuitbox.rb +5 -4
- data/lib/circuitbox/circuit_breaker.rb +18 -20
- data/lib/circuitbox/configuration.rb +5 -9
- data/lib/circuitbox/errors/error.rb +2 -0
- data/lib/circuitbox/errors/open_circuit_error.rb +3 -0
- data/lib/circuitbox/errors/service_failure_error.rb +3 -0
- data/lib/circuitbox/excon_middleware.rb +10 -8
- data/lib/circuitbox/faraday_middleware.rb +5 -2
- data/lib/circuitbox/memory_store.rb +2 -1
- data/lib/circuitbox/memory_store/container.rb +4 -2
- data/lib/circuitbox/memory_store/monotonic_time.rb +2 -0
- data/lib/circuitbox/notifier/null.rb +2 -0
- data/lib/circuitbox/timer.rb +51 -0
- data/lib/circuitbox/version.rb +3 -1
- metadata +78 -22
- data/lib/circuitbox/timer/monotonic.rb +0 -17
- data/lib/circuitbox/timer/null.rb +0 -9
- data/lib/circuitbox/timer/simple.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fb89d6ef46d73dfa35e7c43181112309aa524979ec1285688cc8cebf8d781bd4
|
4
|
+
data.tar.gz: 735c23115ea5127923c05b84d5b6cfe64193521bcd751639cc6ceab32c6b97ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a29d10725e8a1a36eec12985681cd66b7c2b3303cb996bfe72226674230d7c8ef38b02bb5731665edd49c7922b2a9f0072434a2ab33da7f64713875415071420
|
7
|
+
data.tar.gz: 9a165096e2b0e5fe484c433284a3c0b6658f4b880552602cb57b22fcf3ea540302b3d3a0910b31b8f3e1938259ca6394faefd3bffffc6c40bf3104d8d02564ec
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Circuitbox
|
2
2
|
|
3
|
-
|
3
|
+
![Tests](https://github.com/yammer/circuitbox/workflows/Tests/badge.svg) [![Gem Version](https://badge.fury.io/rb/circuitbox.svg)](https://badge.fury.io/rb/circuitbox)
|
4
4
|
|
5
5
|
Circuitbox is a Ruby circuit breaker gem. It protects your application from failures of its service dependencies. It wraps calls to external services and monitors for failures in one minute intervals. Once more than 10 requests have been made with a 50% failure rate, Circuitbox stops sending requests to that failing service for one minute. This helps your application gracefully degrade.
|
6
6
|
Resources about the circuit breaker pattern:
|
@@ -43,7 +43,7 @@ Using the `run` method will throw an exception when the circuit is open or the u
|
|
43
43
|
```
|
44
44
|
|
45
45
|
## Global Configuration
|
46
|
-
Circuitbox has defaults for circuit_store, notifier,
|
46
|
+
Circuitbox has defaults for circuit_store, notifier, and logger.
|
47
47
|
This can be configured through ```Circuitbox.configure```.
|
48
48
|
The circuit cache used by ```Circuitbox.circuit``` will be cleared after running ```Circuitbox.configure```.
|
49
49
|
This means when accessing the circuit through ```Circuitbox.circuit``` any custom configuration options should always be given.
|
@@ -55,7 +55,6 @@ will need to be recreated to pick up the new defaults.
|
|
55
55
|
Circuitbox.configure do |config|
|
56
56
|
config.default_circuit_store = Circuitbox::MemoryStore.new
|
57
57
|
config.default_notifier = Circuitbox::Notifier::Null.new
|
58
|
-
config.default_timer = Circuitbox::Timer::Simple.new
|
59
58
|
config.default_logger = Rails.logger
|
60
59
|
end
|
61
60
|
```
|
@@ -91,12 +90,6 @@ class ExampleServiceClient
|
|
91
90
|
# This overrides what is set in the global configuration
|
92
91
|
logger: Logger.new(STDOUT),
|
93
92
|
|
94
|
-
# Customized Timer object
|
95
|
-
# Use NullTimer if you don't want to time circuit execution
|
96
|
-
# Use MonotonicTimer to avoid bad time metrics on system time resync
|
97
|
-
# This overrides what is set in the global configuration
|
98
|
-
execution_timer: SimpleTimer,
|
99
|
-
|
100
93
|
# Customized notifier
|
101
94
|
# overrides the default
|
102
95
|
# this overrides what is set in the global configuration
|
@@ -168,7 +161,7 @@ end
|
|
168
161
|
|
169
162
|
`payload[:gauge]` can be:
|
170
163
|
|
171
|
-
- `
|
164
|
+
- `runtime` # runtime will only be notified when circuit is closed and block is successfully executed.
|
172
165
|
|
173
166
|
**warnings:**
|
174
167
|
in case of misconfiguration, circuitbox will fire a circuitbox_warning
|
@@ -241,71 +234,6 @@ c.use Circuitbox::FaradayMiddleware, circuit_breaker_options: {}
|
|
241
234
|
c.use Circuitbox::FaradayMiddleware, open_circuit: lambda { |response| response.status >= 500 }
|
242
235
|
```
|
243
236
|
|
244
|
-
## CHANGELOG
|
245
|
-
### v1.1.0
|
246
|
-
- ruby 2.2 support [#58](https://github.com/yammer/circuitbox/pull/58)
|
247
|
-
- configurable logger [#58](https://github.com/yammer/circuitbox/pull/58)
|
248
|
-
|
249
|
-
### v1.0.3
|
250
|
-
- fix timeout issue for default configuration, as default `:Memory` adapter does
|
251
|
-
not natively support expires, we need to actually load it on demand.
|
252
|
-
- fix memoization of `circuit_breaker_options` not actually doing memoization in
|
253
|
-
`excon` and `faraday` middleware.
|
254
|
-
|
255
|
-
### v1.0.2
|
256
|
-
- Fix timeout issue [#51](https://github.com/yammer/circuitbox/issues/51)
|
257
|
-
[sebastian-juliu](https://github.com/sebastian-julius)
|
258
|
-
|
259
|
-
### v1.0.1
|
260
|
-
- Fix Rails integration, as version 1.0.0 removed the rails tasks integration, but missed
|
261
|
-
removing the related railtie.
|
262
|
-
|
263
|
-
### v1.0.0
|
264
|
-
- support for cross process circuitbreakers by swapping the circuitbreaker store for a
|
265
|
-
`Moneta` supported key value store.
|
266
|
-
- Change `FaradayMiddleware` default behaviour to not open on `4xx` errors but just on `5xx`
|
267
|
-
server errors and connection errors
|
268
|
-
- Remove stat store, which was largely unused
|
269
|
-
|
270
|
-
### v0.11.0
|
271
|
-
- fix URI require missing (https://github.com/yammer/circuitbox/pull/42 @gottfrois)
|
272
|
-
- configurable circuitbox store backend via Moneta supporting multi process circuits
|
273
|
-
|
274
|
-
### v0.10.4
|
275
|
-
- Issue #39, keep the original backtrace for the wrapped exception around when
|
276
|
-
re-raising a Circuitbox::Error
|
277
|
-
|
278
|
-
### v0.10.3
|
279
|
-
- Circuitbox::ServiceFailureError wraps the original exception that was raised.
|
280
|
-
The behaviour for to_s wasn't exposing this information and was returning the
|
281
|
-
name of class "Circuitbox::ServiceFailureError". Change the behaviour for to_s
|
282
|
-
to indicate this exception is a wrapper around the original exception.
|
283
|
-
[sherrry](https://github.com/sherrry)
|
284
|
-
|
285
|
-
### v0.10.2
|
286
|
-
- Faraday middleware passes two arguments to the `default_value` callback, not
|
287
|
-
just one. First argument is still the error response from Faraday if there is
|
288
|
-
one. Second argument is the exception that caused the call to fail if it
|
289
|
-
failed before Faraday returned a response. Old behaviour is preserved if you
|
290
|
-
pass a lambda that takes just one argument, but this is deprecated and will be
|
291
|
-
removed in the next version of Circuitbox.
|
292
|
-
[dwaller](https://github.com/dwaller)
|
293
|
-
|
294
|
-
### v0.10.1
|
295
|
-
- [Documentation fix](https://github.com/yammer/circuitbox/pull/29) [chiefcll](https://github.com/chiefcll)
|
296
|
-
- [Faraday middleware fix](https://github.com/yammer/circuitbox/pull/30) [chiefcll](https://github.com/chiefcll)
|
297
|
-
|
298
|
-
### v0.10
|
299
|
-
- configuration option for faraday middleware for what should be considered to open the circuit [enrico-scalavio](https://github.com/enrico-scalavino)
|
300
|
-
- fix for issue 16, support of in_parallel requests in faraday middleware which were opening the circuit.
|
301
|
-
- deprecate the __run_option__ `:storage_key`
|
302
|
-
|
303
|
-
### v0.9
|
304
|
-
- add `run!` method to raise exception on circuit open and service
|
305
|
-
|
306
|
-
### v0.8
|
307
|
-
- Everything prior to keeping the change log
|
308
|
-
|
309
237
|
## Installation
|
310
238
|
|
311
239
|
Add this line to your application's Gemfile:
|
data/lib/circuitbox.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'logger'
|
3
4
|
|
4
5
|
require_relative 'circuitbox/version'
|
@@ -12,12 +13,12 @@ class Circuitbox
|
|
12
13
|
class << self
|
13
14
|
include Configuration
|
14
15
|
|
15
|
-
def circuit(service_name, options)
|
16
|
+
def circuit(service_name, options, &block)
|
16
17
|
circuit = (cached_circuits[service_name] ||= CircuitBreaker.new(service_name, options))
|
17
18
|
|
18
|
-
return circuit unless
|
19
|
+
return circuit unless block
|
19
20
|
|
20
|
-
circuit.run(circuitbox_exceptions: false)
|
21
|
+
circuit.run(circuitbox_exceptions: false, &block)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -7,13 +7,13 @@ class Circuitbox
|
|
7
7
|
include LoggerMessages
|
8
8
|
|
9
9
|
attr_reader :service, :circuit_options, :exceptions,
|
10
|
-
:logger, :circuit_store, :notifier, :time_class
|
10
|
+
:logger, :circuit_store, :notifier, :time_class
|
11
11
|
|
12
12
|
DEFAULTS = {
|
13
|
-
sleep_window:
|
13
|
+
sleep_window: 90,
|
14
14
|
volume_threshold: 5,
|
15
|
-
error_threshold:
|
16
|
-
time_window:
|
15
|
+
error_threshold: 50,
|
16
|
+
time_window: 60
|
17
17
|
}.freeze
|
18
18
|
|
19
19
|
#
|
@@ -30,7 +30,6 @@ class Circuitbox
|
|
30
30
|
@service = service.to_s
|
31
31
|
@circuit_options = DEFAULTS.merge(options)
|
32
32
|
@circuit_store = options.fetch(:cache) { Circuitbox.default_circuit_store }
|
33
|
-
@execution_timer = options.fetch(:execution_timer) { Circuitbox.default_timer }
|
34
33
|
@notifier = options.fetch(:notifier) { Circuitbox.default_notifier }
|
35
34
|
|
36
35
|
if @circuit_options[:timeout_seconds]
|
@@ -39,7 +38,7 @@ class Circuitbox
|
|
39
38
|
end
|
40
39
|
|
41
40
|
@exceptions = options.fetch(:exceptions)
|
42
|
-
raise ArgumentError
|
41
|
+
raise ArgumentError.new('exceptions need to be an array') unless @exceptions.is_a?(Array)
|
43
42
|
|
44
43
|
@logger = options.fetch(:logger) { Circuitbox.default_logger }
|
45
44
|
@time_class = options.fetch(:time_class) { Time }
|
@@ -52,7 +51,7 @@ class Circuitbox
|
|
52
51
|
value.is_a?(Proc) ? value.call : value
|
53
52
|
end
|
54
53
|
|
55
|
-
def run(circuitbox_exceptions: true)
|
54
|
+
def run(circuitbox_exceptions: true, &block)
|
56
55
|
if open?
|
57
56
|
skipped!
|
58
57
|
raise Circuitbox::OpenCircuitError.new(service) if circuitbox_exceptions
|
@@ -60,17 +59,15 @@ class Circuitbox
|
|
60
59
|
logger.debug(circuit_running_message)
|
61
60
|
|
62
61
|
begin
|
63
|
-
response =
|
64
|
-
yield
|
65
|
-
end
|
62
|
+
response = Timer.measure(service, notifier, 'runtime', &block)
|
66
63
|
|
67
64
|
success!
|
68
|
-
rescue *exceptions =>
|
65
|
+
rescue *exceptions => e
|
69
66
|
# Other stores could raise an exception that circuitbox is asked to watch.
|
70
67
|
# setting to nil keeps the same behavior as the previous defination of run.
|
71
68
|
response = nil
|
72
69
|
failure!
|
73
|
-
raise Circuitbox::ServiceFailureError.new(service,
|
70
|
+
raise Circuitbox::ServiceFailureError.new(service, e) if circuitbox_exceptions
|
74
71
|
end
|
75
72
|
end
|
76
73
|
|
@@ -83,7 +80,8 @@ class Circuitbox
|
|
83
80
|
|
84
81
|
def error_rate(failures = failure_count, success = success_count)
|
85
82
|
all_count = failures + success
|
86
|
-
return 0.0 unless all_count
|
83
|
+
return 0.0 unless all_count.positive?
|
84
|
+
|
87
85
|
(failures / all_count.to_f) * 100
|
88
86
|
end
|
89
87
|
|
@@ -99,7 +97,7 @@ class Circuitbox
|
|
99
97
|
circuit_store.delete(open_storage_key)
|
100
98
|
end
|
101
99
|
|
102
|
-
|
100
|
+
private
|
103
101
|
|
104
102
|
def should_open?
|
105
103
|
failures = failure_count
|
@@ -206,12 +204,12 @@ class Circuitbox
|
|
206
204
|
def check_sleep_window
|
207
205
|
sleep_window = option_value(:sleep_window)
|
208
206
|
time_window = option_value(:time_window)
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
207
|
+
return unless sleep_window < time_window
|
208
|
+
|
209
|
+
warning_message = "sleep_window: #{sleep_window} is shorter than time_window: #{time_window}, "\
|
210
|
+
"the error_rate would not be reset after a sleep."
|
211
|
+
notifier.notify_warning(service, warning_message)
|
212
|
+
warn("Circuit: #{service}, Warning: #{warning_message}")
|
215
213
|
end
|
216
214
|
|
217
215
|
def stat_storage_key(event)
|
@@ -1,7 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'memory_store'
|
2
|
-
require_relative 'timer
|
3
|
-
require_relative 'timer/null'
|
4
|
-
require_relative 'timer/simple'
|
4
|
+
require_relative 'timer'
|
5
5
|
require_relative 'notifier/active_support'
|
6
6
|
require_relative 'notifier/null'
|
7
7
|
|
@@ -30,19 +30,15 @@ class Circuitbox
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def default_timer
|
34
|
-
@default_timer ||= Timer::Simple.new
|
35
|
-
end
|
36
|
-
|
37
33
|
def default_logger
|
38
34
|
@default_logger ||= if defined?(Rails)
|
39
35
|
Rails.logger
|
40
36
|
else
|
41
|
-
Logger.new(
|
37
|
+
Logger.new($stdout)
|
42
38
|
end
|
43
39
|
end
|
44
40
|
|
45
|
-
|
41
|
+
private
|
46
42
|
|
47
43
|
def cached_circuits
|
48
44
|
@cached_circuits ||= {}
|
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Circuitbox
|
2
4
|
class ServiceFailureError < Circuitbox::Error
|
3
5
|
attr_reader :service, :original
|
4
6
|
|
5
7
|
def initialize(service, exception)
|
8
|
+
super()
|
6
9
|
@service = service
|
7
10
|
@original = exception
|
8
11
|
# we copy over the original exceptions backtrace if there is one
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'excon'
|
2
4
|
require 'circuitbox'
|
3
5
|
|
@@ -8,7 +10,7 @@ class Circuitbox
|
|
8
10
|
DEFAULT_EXCEPTIONS = [
|
9
11
|
Excon::Errors::Timeout,
|
10
12
|
RequestFailed
|
11
|
-
]
|
13
|
+
].freeze
|
12
14
|
|
13
15
|
class NullResponse < Excon::Response
|
14
16
|
def initialize(response, exception)
|
@@ -26,7 +28,7 @@ class Circuitbox
|
|
26
28
|
|
27
29
|
def initialize(stack, opts = {})
|
28
30
|
@stack = stack
|
29
|
-
default_options = { open_circuit:
|
31
|
+
default_options = { open_circuit: ->(response) { response[:status] >= 400 } }
|
30
32
|
@opts = default_options.merge(opts)
|
31
33
|
super(stack)
|
32
34
|
end
|
@@ -35,8 +37,8 @@ class Circuitbox
|
|
35
37
|
circuit(datum).run do
|
36
38
|
raise RequestFailed
|
37
39
|
end
|
38
|
-
rescue Circuitbox::Error =>
|
39
|
-
circuit_open_value(datum, datum[:response],
|
40
|
+
rescue Circuitbox::Error => e
|
41
|
+
circuit_open_value(datum, datum[:response], e)
|
40
42
|
end
|
41
43
|
|
42
44
|
def request_call(datum)
|
@@ -50,8 +52,8 @@ class Circuitbox
|
|
50
52
|
raise RequestFailed if open_circuit?(datum[:response])
|
51
53
|
end
|
52
54
|
@stack.response_call(datum)
|
53
|
-
rescue Circuitbox::Error =>
|
54
|
-
circuit_open_value(datum, datum[:response],
|
55
|
+
rescue Circuitbox::Error => e
|
56
|
+
circuit_open_value(datum, datum[:response], e)
|
55
57
|
end
|
56
58
|
|
57
59
|
def identifier
|
@@ -93,9 +95,9 @@ class Circuitbox
|
|
93
95
|
def default_value
|
94
96
|
@default_value ||= begin
|
95
97
|
default = opts.fetch(:default_value) do
|
96
|
-
|
98
|
+
->(response, exception) { NullResponse.new(response, exception) }
|
97
99
|
end
|
98
|
-
default.respond_to?(:call) ? default :
|
100
|
+
default.respond_to?(:call) ? default : ->(*) { default }
|
99
101
|
end
|
100
102
|
end
|
101
103
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'faraday'
|
2
4
|
require 'circuitbox'
|
3
5
|
|
@@ -7,6 +9,7 @@ class Circuitbox
|
|
7
9
|
|
8
10
|
class NullResponse < Faraday::Response
|
9
11
|
attr_reader :original_response, :original_exception
|
12
|
+
|
10
13
|
def initialize(response = nil, exception = nil)
|
11
14
|
@original_response = response
|
12
15
|
@original_exception = exception
|
@@ -60,8 +63,8 @@ class Circuitbox
|
|
60
63
|
raise RequestFailed if open_circuit?(service_response)
|
61
64
|
end
|
62
65
|
end
|
63
|
-
rescue Circuitbox::Error =>
|
64
|
-
circuit_open_value(request_env, service_response,
|
66
|
+
rescue Circuitbox::Error => e
|
67
|
+
circuit_open_value(request_env, service_response, e)
|
65
68
|
end
|
66
69
|
|
67
70
|
private
|
@@ -51,7 +51,7 @@ class Circuitbox
|
|
51
51
|
@mutex.synchronize { @store.delete(key) }
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
private
|
55
55
|
|
56
56
|
def fetch_container(key)
|
57
57
|
current_time = current_second
|
@@ -73,6 +73,7 @@ class Circuitbox
|
|
73
73
|
def fetch_value(key)
|
74
74
|
container = fetch_container(key)
|
75
75
|
return unless container
|
76
|
+
|
76
77
|
container.value
|
77
78
|
end
|
78
79
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'monotonic_time'
|
2
4
|
|
3
5
|
class Circuitbox
|
@@ -13,11 +15,11 @@ class Circuitbox
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def expired?
|
16
|
-
@expires_after
|
18
|
+
@expires_after.positive? && @expires_after < current_second
|
17
19
|
end
|
18
20
|
|
19
21
|
def expired_at?(clock_second)
|
20
|
-
@expires_after
|
22
|
+
@expires_after.positive? && @expires_after < clock_second
|
21
23
|
end
|
22
24
|
|
23
25
|
def expires_after(seconds = 0)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Circuitbox
|
4
|
+
class Timer
|
5
|
+
class Monotonic
|
6
|
+
class << self
|
7
|
+
def supported?
|
8
|
+
defined?(Process::CLOCK_MONOTONIC)
|
9
|
+
end
|
10
|
+
|
11
|
+
def now
|
12
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Default
|
18
|
+
class << self
|
19
|
+
def supported?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def now
|
24
|
+
Time.now.to_f
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def measure(service, notifier, metric_name)
|
31
|
+
before = now
|
32
|
+
result = yield
|
33
|
+
total_time = now - before
|
34
|
+
notifier.metric_gauge(service, metric_name, total_time)
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
if Monotonic.supported?
|
41
|
+
def now
|
42
|
+
Monotonic.now
|
43
|
+
end
|
44
|
+
else
|
45
|
+
def now
|
46
|
+
Default.now
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/circuitbox/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: circuitbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.pre4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fahim Ferdous
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-01-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -45,7 +45,7 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '0.
|
48
|
+
version: '0.8'
|
49
49
|
- - "<"
|
50
50
|
- !ruby/object:Gem::Version
|
51
51
|
version: '2.0'
|
@@ -55,7 +55,7 @@ dependencies:
|
|
55
55
|
requirements:
|
56
56
|
- - ">="
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
version: '0.
|
58
|
+
version: '0.8'
|
59
59
|
- - "<"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '2.0'
|
@@ -115,6 +115,20 @@ dependencies:
|
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '1.7'
|
118
|
+
- !ruby/object:Gem::Dependency
|
119
|
+
name: moneta
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.0'
|
125
|
+
type: :development
|
126
|
+
prerelease: false
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.0'
|
118
132
|
- !ruby/object:Gem::Dependency
|
119
133
|
name: rack
|
120
134
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,47 +158,89 @@ dependencies:
|
|
144
158
|
- !ruby/object:Gem::Version
|
145
159
|
version: '13.0'
|
146
160
|
- !ruby/object:Gem::Dependency
|
147
|
-
name:
|
161
|
+
name: rubocop
|
148
162
|
requirement: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
|
-
- -
|
164
|
+
- - '='
|
151
165
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
166
|
+
version: 1.8.1
|
153
167
|
type: :development
|
154
168
|
prerelease: false
|
155
169
|
version_requirements: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
|
-
- -
|
171
|
+
- - '='
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version:
|
173
|
+
version: 1.8.1
|
160
174
|
- !ruby/object:Gem::Dependency
|
161
|
-
name:
|
175
|
+
name: rubocop-minitest
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - '='
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 0.10.3
|
181
|
+
type: :development
|
182
|
+
prerelease: false
|
183
|
+
version_requirements: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - '='
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: 0.10.3
|
188
|
+
- !ruby/object:Gem::Dependency
|
189
|
+
name: rubocop-performance
|
190
|
+
requirement: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - '='
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: 1.9.2
|
195
|
+
type: :development
|
196
|
+
prerelease: false
|
197
|
+
version_requirements: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - '='
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 1.9.2
|
202
|
+
- !ruby/object:Gem::Dependency
|
203
|
+
name: rubocop-rake
|
204
|
+
requirement: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - '='
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 0.5.1
|
209
|
+
type: :development
|
210
|
+
prerelease: false
|
211
|
+
version_requirements: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - '='
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: 0.5.1
|
216
|
+
- !ruby/object:Gem::Dependency
|
217
|
+
name: timecop
|
162
218
|
requirement: !ruby/object:Gem::Requirement
|
163
219
|
requirements:
|
164
220
|
- - "~>"
|
165
221
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
222
|
+
version: '0.9'
|
167
223
|
type: :development
|
168
224
|
prerelease: false
|
169
225
|
version_requirements: !ruby/object:Gem::Requirement
|
170
226
|
requirements:
|
171
227
|
- - "~>"
|
172
228
|
- !ruby/object:Gem::Version
|
173
|
-
version: '
|
229
|
+
version: '0.9'
|
174
230
|
- !ruby/object:Gem::Dependency
|
175
|
-
name:
|
231
|
+
name: typhoeus
|
176
232
|
requirement: !ruby/object:Gem::Requirement
|
177
233
|
requirements:
|
178
234
|
- - "~>"
|
179
235
|
- !ruby/object:Gem::Version
|
180
|
-
version: '1.
|
236
|
+
version: '1.3'
|
181
237
|
type: :development
|
182
238
|
prerelease: false
|
183
239
|
version_requirements: !ruby/object:Gem::Requirement
|
184
240
|
requirements:
|
185
241
|
- - "~>"
|
186
242
|
- !ruby/object:Gem::Version
|
187
|
-
version: '1.
|
243
|
+
version: '1.3'
|
188
244
|
description:
|
189
245
|
email:
|
190
246
|
- fahimfmf@gmail.com
|
@@ -208,14 +264,15 @@ files:
|
|
208
264
|
- lib/circuitbox/memory_store/monotonic_time.rb
|
209
265
|
- lib/circuitbox/notifier/active_support.rb
|
210
266
|
- lib/circuitbox/notifier/null.rb
|
211
|
-
- lib/circuitbox/timer
|
212
|
-
- lib/circuitbox/timer/null.rb
|
213
|
-
- lib/circuitbox/timer/simple.rb
|
267
|
+
- lib/circuitbox/timer.rb
|
214
268
|
- lib/circuitbox/version.rb
|
215
269
|
homepage: https://github.com/yammer/circuitbox
|
216
270
|
licenses:
|
217
271
|
- Apache-2.0
|
218
|
-
metadata:
|
272
|
+
metadata:
|
273
|
+
bug_tracker_uri: https://github.com/yammer/circuitbox/issues
|
274
|
+
changelog_uri: https://github.com/yammer/circuitbox/blob/main/CHANGELOG.md
|
275
|
+
source_code_uri: https://github.com/yammer/circuitbox
|
219
276
|
post_install_message:
|
220
277
|
rdoc_options: []
|
221
278
|
require_paths:
|
@@ -224,15 +281,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
224
281
|
requirements:
|
225
282
|
- - ">="
|
226
283
|
- !ruby/object:Gem::Version
|
227
|
-
version:
|
284
|
+
version: 2.4.0
|
228
285
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
229
286
|
requirements:
|
230
287
|
- - ">"
|
231
288
|
- !ruby/object:Gem::Version
|
232
289
|
version: 1.3.1
|
233
290
|
requirements: []
|
234
|
-
|
235
|
-
rubygems_version: 2.5.2.3
|
291
|
+
rubygems_version: 3.1.4
|
236
292
|
signing_key:
|
237
293
|
specification_version: 4
|
238
294
|
summary: A robust circuit breaker that manages failing external services.
|
@@ -1,17 +0,0 @@
|
|
1
|
-
class Circuitbox
|
2
|
-
class Timer
|
3
|
-
class Monotonic
|
4
|
-
def initialize(time_unit = :millisecond)
|
5
|
-
@time_unit = time_unit
|
6
|
-
end
|
7
|
-
|
8
|
-
def time(service, notifier, metric_name)
|
9
|
-
before = Process.clock_gettime(Process::CLOCK_MONOTONIC, @time_unit)
|
10
|
-
result = yield
|
11
|
-
total_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, @time_unit) - before
|
12
|
-
notifier.metric_gauge(service, metric_name, total_time)
|
13
|
-
result
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
class Circuitbox
|
2
|
-
class Timer
|
3
|
-
class Simple
|
4
|
-
def time(service, notifier, metric_name)
|
5
|
-
before = Time.now.to_f
|
6
|
-
result = yield
|
7
|
-
total_time = Time.now.to_f - before
|
8
|
-
notifier.metric_gauge(service, metric_name, total_time)
|
9
|
-
result
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|