shift-circuit-breaker 0.2.1 → 0.2.2

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
- SHA1:
3
- metadata.gz: 6535db8c80cfc5b58b0741994700a0921d3c8966
4
- data.tar.gz: 9b10e2822b263229c819e4e00898853242dcf3f0
2
+ SHA256:
3
+ metadata.gz: bda401bde485debfe14c8dfd0ce54701967e877d2e4839a54b268ed85980daef
4
+ data.tar.gz: a4f3eb047181e8a48c43de680d27098d90c3c6862cece5664f5e4ae5d3c7a836
5
5
  SHA512:
6
- metadata.gz: 5310e8cdfb5c8951fb70fe41059befa851b76d9d70c838b7d10abdb03616008bb2b1f728fa5ea02351c0365d52fea1d5ed7751c495d3af4bba7fb0d1f9beb091
7
- data.tar.gz: 681d7e60c9139f48e5abcabf6413e08f202224dfe4c7a9e7b7ec6a22690036b81ca33f60fe779acac334e533ada5fcf0b01676f3f316072a6da5bcd35ff513de
6
+ metadata.gz: ea8da391a6b84eefb37961224417ba54bb7fc967d1e8b9a8178fcaee75ad4a89b75e2f0d7820031f74cedb89aa7f73de2533470b629b4bd898bc7093dd9dfa6c
7
+ data.tar.gz: 51d1f97c57448055dca2222c0e1d98909bf15903503811b96ca14b4f1b6b7b2a562891d65445e0a0c890bfcacaf84ccf73cfbb5db516c73b9e263360accf55f7
@@ -7,5 +7,8 @@ plugins:
7
7
  - ruby
8
8
  reek:
9
9
  enabled: true
10
+ checks:
11
+ Attribute:
12
+ enabled: false
10
13
  rubocop:
11
14
  enabled: true
@@ -27,6 +27,7 @@ module Shift
27
27
  # CIRCUIT_BREAKER = Shift::CircuitBreaker.new(:an_identifier_for_the_circuit,
28
28
  # error_threshold: 10,
29
29
  # skip_duration: 60,
30
+ # log_errors: true,
30
31
  # additional_exception_classes: [Faraday::ClientError]
31
32
  # )
32
33
  #
@@ -13,9 +13,11 @@ module Shift
13
13
  # the defined skip_duration, ie. no operations are executed and the provided fallback is called.
14
14
  #
15
15
  class CircuitHandler
16
- attr_accessor :name, :error_threshold, :skip_duration, :exception_classes, :error_count, :last_error_time, :state, :logger, :monitor
16
+ attr_accessor :name, :error_threshold, :skip_duration, :exception_classes, :error_logging_enabled, :error_count
17
+ attr_accessor :last_error_time, :state, :logger, :monitor
17
18
 
18
19
  DEFAULT_EXCEPTION_CLASSES = [Net::OpenTimeout, Net::ReadTimeout, Faraday::TimeoutError, Timeout::Error].freeze
20
+ DEFAULT_ERROR_LOGGING_STATE = true
19
21
 
20
22
  # Initializer creates an instance of the service
21
23
  #
@@ -23,24 +25,27 @@ module Shift
23
25
  # @param [Integer] error_threshold - The minimum error threshold required for the circuit to be opened/tripped
24
26
  # @param [Integer] skip_duration - The duration in seconds the circuit should be open for before operations are allowed through/executed
25
27
  # @param [Array] additional_exception_classes - Any additional exception classes to rescue along the DEFAULT_EXCEPTION_CLASSES
28
+ # @param [Boolean] error_logging_enabled - Decided whether to log errors or not. Still they will be monitored
26
29
  # @param [Object] logger - service to handle error logging
27
30
  # @param [Object] monitor - service to monitor metric
28
31
  def initialize(name,
29
32
  error_threshold:,
30
33
  skip_duration:,
31
34
  additional_exception_classes: [],
35
+ error_logging_enabled: DEFAULT_ERROR_LOGGING_STATE,
32
36
  logger: Shift::CircuitBreaker::CircuitLogger.new,
33
37
  monitor: Shift::CircuitBreaker::CircuitMonitor.new)
34
38
 
35
- self.name = name
36
- self.error_threshold = error_threshold
37
- self.skip_duration = skip_duration
38
- self.exception_classes = (additional_exception_classes | DEFAULT_EXCEPTION_CLASSES)
39
- self.logger = logger
40
- self.monitor = monitor
41
- self.error_count = 0
42
- self.last_error_time = nil
43
- self.state = :closed
39
+ self.name = name
40
+ self.error_threshold = error_threshold
41
+ self.skip_duration = skip_duration
42
+ self.error_logging_enabled = error_logging_enabled
43
+ self.exception_classes = (additional_exception_classes | DEFAULT_EXCEPTION_CLASSES)
44
+ self.logger = logger
45
+ self.monitor = monitor
46
+ self.error_count = 0
47
+ self.last_error_time = nil
48
+ self.state = :closed
44
49
  end
45
50
 
46
51
  # Performs the given operation within the circuit
@@ -98,10 +103,14 @@ module Shift
98
103
  def handle_exception(exception, fallback)
99
104
  record_error
100
105
  set_state
106
+ log_errors(exception)
101
107
  monitor.record_metric(name, state)
102
- logger.error(circuit_name: name, state: state, error_message: exception.message)
103
108
  fallback.call
104
109
  end
110
+
111
+ def log_errors(exception)
112
+ logger.error(circuit_name: name, state: state, error_message: exception.message) if error_logging_enabled
113
+ end
105
114
  end
106
115
  end
107
116
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Shift
4
4
  module CircuitBreaker
5
- VERSION = "0.2.1"
5
+ VERSION = "0.2.2"
6
6
  end
7
7
  end
@@ -137,6 +137,55 @@ module Shift
137
137
  end
138
138
  end
139
139
  end
140
+
141
+ context "Error Logging" do
142
+ let(:default_error_threshold) { 5 }
143
+ let(:default_skip_duration) { 6 }
144
+
145
+ context "when it is enabled" do
146
+ it "should log errors" do
147
+ # Arrange
148
+ operation_stub = instance_double("Operation")
149
+ fallback_stub = instance_double("Fallback")
150
+ error_logger = instance_double("Error")
151
+
152
+ allow(operation_stub).to receive(:perform_task).and_raise(Timeout::Error, "Request Timeout")
153
+ allow(error_logger).to receive(:error).and_return({})
154
+ # Act
155
+ cb = described_class.new(:test_circuit_breaker, error_threshold: default_error_threshold, skip_duration: default_skip_duration, logger: error_logger)
156
+ operation_result = cb.call(operation: -> { operation_stub.perform_task }, fallback: -> { fallback_stub })
157
+
158
+ # Assert
159
+ aggregate_failures do
160
+ expect(operation_result).to eq(fallback_stub)
161
+ expect(cb.error_count).to eq(1)
162
+ expect(error_logger).to have_received(:error)
163
+ end
164
+ end
165
+ end
166
+
167
+ context "when it is disabled" do
168
+ it "should not log errors" do
169
+ # Arrange
170
+ operation_stub = instance_double("Operation")
171
+ fallback_stub = instance_double("Fallback")
172
+ error_logger = instance_double("Error")
173
+
174
+ allow(operation_stub).to receive(:perform_task).and_raise(Timeout::Error, "Request Timeout")
175
+ allow(error_logger).to receive(:error).and_return({})
176
+ # Act
177
+ cb = described_class.new(:test_circuit_breaker, error_threshold: default_error_threshold, skip_duration: default_skip_duration, error_logging_enabled: false, logger: error_logger)
178
+ operation_result = cb.call(operation: -> { operation_stub.perform_task }, fallback: -> { fallback_stub })
179
+
180
+ # Assert
181
+ aggregate_failures do
182
+ expect(operation_result).to eq(fallback_stub)
183
+ expect(cb.error_count).to eq(1)
184
+ expect(error_logger).not_to have_received(:error)
185
+ end
186
+ end
187
+ end
188
+ end
140
189
  end
141
190
  end
142
191
  end
@@ -20,7 +20,7 @@ module Shift
20
20
  operation_stub = instance_double("Operation")
21
21
  fallback_stub = instance_double("Fallback")
22
22
  expected_result_stub = instance_double("ExpectedResult")
23
- bb
23
+
24
24
  allow(monitor_stub).to receive(:record_metric)
25
25
  allow(operation_stub).to receive(:perform_task).and_return(expected_result_stub)
26
26
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shift-circuit-breaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mufudzi Masaire
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-22 00:00:00.000000000 Z
11
+ date: 2018-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -223,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
223
  version: '0'
224
224
  requirements: []
225
225
  rubyforge_project:
226
- rubygems_version: 2.5.1
226
+ rubygems_version: 2.7.7
227
227
  signing_key:
228
228
  specification_version: 4
229
229
  summary: A generic implementation of the Circuit Breaker pattern in Ruby