circuitbox 2.0.0.pre5 → 2.0.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 +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
|
 [](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:
|