circuitbox 2.0.0.pre5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +21 -56
- data/lib/circuitbox/configuration.rb +14 -0
- data/lib/circuitbox/version.rb +1 -1
- data/lib/circuitbox.rb +22 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 206d564d542dc903001281052403166a100732fc9b2b0f1f0999601e4543893b
|
4
|
+
data.tar.gz: '0095c6111ab38a311cb48ae8df82906185cef5b2b3ee8e761f08c9bacfb95782'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 314fe848d0dfbcc1aab3b71f469349b950b3dd117df76fcc88d2e37da574ce03000a9f6b62f712d7e4d1b069d5428d12d75d29bb91410ed4c0a83d8a6bfd41ae
|
7
|
+
data.tar.gz: 613f95add06ef602442bcde07b62f12d2fdee60c5713fcb72b71d09ddcbe8085340ffdcbd9ad83161cf31b55536c2e9ec5cce0beaddfac3737fd7a39c62aec3f
|
data/README.md
CHANGED
@@ -2,10 +2,16 @@
|
|
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
|
-
Circuitbox is a Ruby circuit breaker gem.
|
5
|
+
Circuitbox is a Ruby circuit breaker gem.
|
6
|
+
It protects your application from failures of its service dependencies.
|
7
|
+
It wraps calls to external services and monitors for failures in one minute intervals.
|
8
|
+
Using a circuit's defaults once more than 5 requests have been made with a 50% failure rate, Circuitbox stops sending requests to that failing service for 90 seconds.
|
9
|
+
This helps your application gracefully degrade.
|
10
|
+
|
6
11
|
Resources about the circuit breaker pattern:
|
7
12
|
* [http://martinfowler.com/bliki/CircuitBreaker.html](http://martinfowler.com/bliki/CircuitBreaker.html)
|
8
|
-
|
13
|
+
|
14
|
+
*Upgrading to 2.x? See [2.0 upgrade](docs/2.0-upgrade.md)*
|
9
15
|
|
10
16
|
## Usage
|
11
17
|
|
@@ -43,13 +49,17 @@ Using the `run` method will throw an exception when the circuit is open or the u
|
|
43
49
|
```
|
44
50
|
|
45
51
|
## Global Configuration
|
46
|
-
Circuitbox has defaults for circuit_store and notifier.
|
47
|
-
This can be configured through ```Circuitbox.configure```.
|
48
|
-
The circuit cache used by ```Circuitbox.circuit``` will be cleared after running ```Circuitbox.configure```.
|
49
|
-
This means when accessing the circuit through ```Circuitbox.circuit``` any custom configuration options should always be given.
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
+
Circuitbox defaults can be configured through ```Circuitbox.configure```.
|
54
|
+
There are two defaults that can be configured:
|
55
|
+
* `default_circuit_store` - Defaults to a `Circuitbox::MemoryStore`. This can be changed to a compatible Moneta store.
|
56
|
+
* `default_notifier` - Defaults to `Circuitbox::Notifier::ActiveSupport` if `ActiveSupport::Notifications` is defined, otherwise defaults to `Circuitbox::Notifier::Null`
|
57
|
+
|
58
|
+
After configuring circuitbox through `Circuitbox.configure`, the internal circuit cache of `Circuitbox.circuit` is cleared.
|
59
|
+
|
60
|
+
Any circuit created manually through ```Circuitbox::CircuitBreaker``` before updating the configuration will need to be recreated to pick up the new defaults.
|
61
|
+
|
62
|
+
The following is an example Circuitbox configuration:
|
53
63
|
|
54
64
|
```ruby
|
55
65
|
Circuitbox.configure do |config|
|
@@ -86,7 +96,6 @@ class ExampleServiceClient
|
|
86
96
|
error_threshold: 50,
|
87
97
|
|
88
98
|
# Customized notifier
|
89
|
-
# overrides the default
|
90
99
|
# this overrides what is set in the global configuration
|
91
100
|
notifier: Notifier.new
|
92
101
|
})
|
@@ -107,12 +116,13 @@ Circuitbox.circuit(:yammer, {
|
|
107
116
|
|
108
117
|
Holds all the relevant data to trip the circuit if a given number of requests
|
109
118
|
fail in a specified period of time. Circuitbox also supports
|
110
|
-
[Moneta](https://github.com/
|
119
|
+
[Moneta](https://github.com/moneta-rb/moneta). As moneta is not a dependency of circuitbox
|
111
120
|
it needs to be loaded prior to use. There are a lot of moneta stores to choose from but
|
112
121
|
some pre-requisits need to be satisfied first:
|
113
122
|
|
114
123
|
- Needs to support increment, this is true for most but not all available stores.
|
115
124
|
- Needs to support expiry.
|
125
|
+
- Needs to support bulk read.
|
116
126
|
- Needs to support concurrent access if you share them. For example sharing a
|
117
127
|
KyotoCabinet store across process fails because the store is single writer
|
118
128
|
multiple readers, and all circuits sharing the store need to be able to write.
|
@@ -120,52 +130,7 @@ some pre-requisits need to be satisfied first:
|
|
120
130
|
|
121
131
|
## Notifications
|
122
132
|
|
123
|
-
|
124
|
-
The active support notifier is used if `ActiveSupport::Notifications` is defined when circuitbox is loaded.
|
125
|
-
If `ActiveSupport::Notifications` is not defined the null notifier is used.
|
126
|
-
The null notifier does not send notifications anywhere.
|
127
|
-
|
128
|
-
The default notifier can be changed to use a specific built in notifier or a custom notifier when [configuring circuitbox](#global-configuration).
|
129
|
-
|
130
|
-
### ActiveSupport
|
131
|
-
Usage example:
|
132
|
-
|
133
|
-
**Circuit open/close:**
|
134
|
-
|
135
|
-
```ruby
|
136
|
-
ActiveSupport::Notifications.subscribe('open.circuitbox') do |_name, _start, _finish, _id, payload|
|
137
|
-
circuit_name = payload[:circuit]
|
138
|
-
Rails.logger.warn("Open circuit for: #{circuit_name}")
|
139
|
-
end
|
140
|
-
ActiveSupport::Notifications.subscribe('close.circuitbox') do |_name, _start, _finish, _id, payload|
|
141
|
-
circuit_name = payload[:circuit]
|
142
|
-
Rails.logger.info("Close circuit for: #{circuit_name}")
|
143
|
-
end
|
144
|
-
```
|
145
|
-
|
146
|
-
**Circuit run:**
|
147
|
-
|
148
|
-
```ruby
|
149
|
-
ActiveSupport::Notifications.subscribe('run.circuitbox') do |*args|
|
150
|
-
event = ActiveSupport::Notifications::Event.new(*args)
|
151
|
-
circuit_name = event.payload[:circuit_name]
|
152
|
-
|
153
|
-
Rails.logger.info("Circuit: #{circuit_name} Runtime: #{event.duration}")
|
154
|
-
end
|
155
|
-
```
|
156
|
-
|
157
|
-
**Circuit Warnings:**
|
158
|
-
In case of misconfiguration, circuitbox will fire a `warning.circuitbox`
|
159
|
-
notification.
|
160
|
-
|
161
|
-
```ruby
|
162
|
-
ActiveSupport::Notifications.subscribe('warning.circuitbox') do |_name, _start, _finish, _id, payload|
|
163
|
-
circuit_name = payload[:circuit]
|
164
|
-
warning = payload[:message]
|
165
|
-
Rails.logger.warning("Circuit warning for: #{circuit_name} Message: #{warning}")
|
166
|
-
end
|
167
|
-
|
168
|
-
```
|
133
|
+
See [Circuit Notifications](docs/circuit_notifications.md)
|
169
134
|
|
170
135
|
## Faraday
|
171
136
|
|
@@ -19,16 +19,30 @@ class Circuitbox
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
# Configure Circuitbox's defaults
|
23
|
+
# After configuring the cached circuits are cleared
|
24
|
+
#
|
25
|
+
# @yieldparam [Circuitbox::Configuration] Circuitbox configuration
|
26
|
+
#
|
22
27
|
def configure
|
23
28
|
yield self
|
24
29
|
clear_cached_circuits!
|
25
30
|
nil
|
26
31
|
end
|
27
32
|
|
33
|
+
# Circuit store used by circuits that are not configured with a specific circuit store
|
34
|
+
# Defaults to Circuitbox::MemoryStore
|
35
|
+
#
|
36
|
+
# @return [Circuitbox::MemoryStore, Moneta] Circuit store
|
28
37
|
def default_circuit_store
|
29
38
|
@default_circuit_store ||= MemoryStore.new
|
30
39
|
end
|
31
40
|
|
41
|
+
# Notifier used by circuits that are not configured with a specific notifier.
|
42
|
+
# If ActiveSupport::Notifications is defined it defaults to Circuitbox::Notifier::ActiveSupport
|
43
|
+
# Otherwise it defaults to Circuitbox::Notifier::Null
|
44
|
+
#
|
45
|
+
# @return [Circuitbox::Notifier::ActiveSupport, Circuitbox::Notifier::Null] Notifier
|
32
46
|
def default_notifier
|
33
47
|
@default_notifier ||= if defined?(ActiveSupport::Notifications)
|
34
48
|
Notifier::ActiveSupport.new
|
data/lib/circuitbox/version.rb
CHANGED
data/lib/circuitbox.rb
CHANGED
@@ -11,6 +11,28 @@ class Circuitbox
|
|
11
11
|
extend Configuration
|
12
12
|
|
13
13
|
class << self
|
14
|
+
# @overload circuit(service_name, options = {})
|
15
|
+
# Returns a Circuitbox::CircuitBreaker for the given service_name
|
16
|
+
#
|
17
|
+
# @param service_name [String, Symbol] Name of the service
|
18
|
+
# Mixing Symbols/Strings for the same service (:test/'test') will result in
|
19
|
+
# multiple circuits being created that point to the same service.
|
20
|
+
# @param options [Hash] Options for the circuit (See Circuitbox::CircuitBreaker#initialize options)
|
21
|
+
# Any configuration options should always be passed when calling this method.
|
22
|
+
# @return [Circuitbox::CircuitBreaker] CircuitBreaker for the given service_name
|
23
|
+
#
|
24
|
+
# @overload circuit(service_name, options = {}, &block)
|
25
|
+
# Runs the circuit with the given block
|
26
|
+
# The circuit's run method is called with `exception` set to false
|
27
|
+
#
|
28
|
+
# @param service_name [String, Symbol] Name of the service
|
29
|
+
# Mixing Symbols/Strings for the same service (:test/'test') will result in
|
30
|
+
# multiple circuits being created that point to the same service.
|
31
|
+
# @param options [Hash] Options for the circuit (See Circuitbox::CircuitBreaker#initialize options)
|
32
|
+
# Any configuration options should always be passed when calling this method.
|
33
|
+
#
|
34
|
+
# @return [Object] The result of the block
|
35
|
+
# @return [nil] If the circuit is open
|
14
36
|
def circuit(service_name, options, &block)
|
15
37
|
circuit = find_or_create_circuit_breaker(service_name, options)
|
16
38
|
|
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
|
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: 2023-04
|
12
|
+
date: 2023-05-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -250,9 +250,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
250
250
|
version: 2.6.0
|
251
251
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
252
252
|
requirements:
|
253
|
-
- - "
|
253
|
+
- - ">="
|
254
254
|
- !ruby/object:Gem::Version
|
255
|
-
version:
|
255
|
+
version: '0'
|
256
256
|
requirements: []
|
257
257
|
rubygems_version: 3.1.6
|
258
258
|
signing_key:
|