msmg_public 0.2.1 → 0.3.1

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: 25086e4748d3390c13f01005abcff52c8e155de8
4
- data.tar.gz: f09f31683695206c76087f1cd6c2d6ba1867aa36
3
+ metadata.gz: c0341374246f0297760ce71ebd29c4dee20d0b10
4
+ data.tar.gz: 7a8e1bcf7b8227172f7e820b1a633fbb3534b39c
5
5
  SHA512:
6
- metadata.gz: d26eb671838f3374f11c5905ac473a505a819435cc87a73a5cf639106baa74445bc614fc2583d84d94a81b8fa1aa0f5099982d3ad058ef470d35f08dceed81f4
7
- data.tar.gz: 730b9fee5a7999645707f42bb6f3314fe32a55eb1453a95aba4e5a20e7a1fc35e1d01a2d939d9baa652ea88643c073f1452afa5d710b431a1b103dd9f44d1c78
6
+ metadata.gz: d7f80341ccfbf70bc2e28f4557e8c722f135ad85e50cda708719e3a6da9743f765a701fd30fc9a46e8e2615ed1187b8a869b2261ac6b5ab87ca96650f0bb5b52
7
+ data.tar.gz: 3b83a70c33caf14ca50aa487c84b0b64116449db1cf9475597c890e900ccaca01f47d97cc4cb4d94505aa7dbbdc65871e00c26ab0b5ba0e59a6abb96f90795d2
@@ -0,0 +1,38 @@
1
+ # Generic WithRetries mixin
2
+
3
+ # Use to propagate exceptions from the inner block to with_retries handler
4
+ class WrappableError < StandardError
5
+ attr_reader :wrapped
6
+
7
+ def initialize(ex)
8
+ super
9
+ @wrapped = ex
10
+ end
11
+ end
12
+
13
+ # Generic WithRetries mixin
14
+ module WithRetries
15
+ # Generic with_retries method
16
+ # rubocop:disable Metrics/MethodLength
17
+ def with_retries(retries, operation: 'Operation',
18
+ log_method: Kernel.method(:puts))
19
+ attempt = 1
20
+ last_ex = nil
21
+ loop do
22
+ begin
23
+ rval = yield
24
+ last_ex = nil
25
+ return rval if rval
26
+ rescue WrappableError => ex
27
+ # Stash the wrapped exception for later use
28
+ last_ex = ex.wrapped
29
+ end
30
+ log_method.call "#{operation} failed #{attempt}/#{retries} attempts"
31
+ break if (attempt += 1) > retries
32
+ end
33
+ log_method.call "#{operation} attempts totally failed"
34
+ raise last_ex if last_ex
35
+ nil
36
+ end
37
+ # rubocop:enable all
38
+ end
data/msmg_public.gemspec CHANGED
@@ -9,7 +9,7 @@ $LOAD_PATH.merge! [File.expand_path('../lib', __FILE__)]
9
9
  Gem::Specification.new do |spec|
10
10
  raise 'RubyGems 2.0 or newer is required.' unless spec.respond_to?(:metadata)
11
11
  spec.name = 'msmg_public'
12
- spec.version = '0.2.1'
12
+ spec.version = '0.3.1'
13
13
  spec.authors = ['Andrew Smith']
14
14
  spec.email = ['andrew.smith at moneysupermarket.com']
15
15
 
data/readme.md CHANGED
@@ -140,3 +140,36 @@ Allows definition of mandatory and optional attributes that are enforced during
140
140
  => `block in build': Unknown field @f used in build (ArgumentError)
141
141
 
142
142
  ```
143
+
144
+ ## WithRetries
145
+
146
+ A general retries mixin and exception wrapper class.
147
+
148
+ ```
149
+ class Foo
150
+ include WithRetries
151
+ FETCH_TRIES = 5
152
+
153
+ def run
154
+ with_retries(FETCH_TRIES, operation: 'Fetching values') do
155
+ begin
156
+ fetchvals
157
+ rescue SomeErrorThatICanRetryOn, SocketError => ex
158
+ raise WrappableError, ex
159
+ end
160
+ end
161
+ end
162
+
163
+ private
164
+
165
+ def fetchvals
166
+ ...
167
+ end
168
+ end
169
+ ```
170
+
171
+ with_retries implements an automatic retry around a block of code retrying if a nil or false value ends the block.
172
+
173
+ It also handles WrappableError exceptions which allow exceptions that can be cared for within the retry to be inhibited until all tries have been performed.
174
+
175
+ The operation parameter allows some tuning of log messages produced by the mixin and the log_method parameter can be used to change the method used to produce log messages during the retries.
@@ -7,6 +7,11 @@ class TestBuilder
7
7
  attr_mandatory :b, :c
8
8
  attr_optional :d
9
9
 
10
+ def initialize
11
+ super
12
+ @d = nil
13
+ end
14
+
10
15
  def sum
11
16
  d = @d || 0
12
17
  @a + @b + @c + d
@@ -0,0 +1,36 @@
1
+ require 'minitest/autorun'
2
+ require 'with_retries'
3
+
4
+ # Unit Test
5
+ class TestWithRetries < Minitest::Test
6
+ include WithRetries
7
+
8
+ def test_no_exceptions
9
+ fails = 3
10
+ tries = 0
11
+ with_retries(5) do
12
+ tries += 1
13
+ (fails -= 1).zero?
14
+ end
15
+ assert_equal(3, tries)
16
+ end
17
+
18
+ # rubocop:disable Metrics/MethodLength ok
19
+ def test_exception_prop
20
+ tries = 0
21
+ # Inner block must wrap any errors that should not be immediately fatal
22
+ # eventually they are propagated out as the original error
23
+ assert_raises(StandardError) do
24
+ with_retries(5) do
25
+ begin
26
+ tries += 1
27
+ raise 'Error'
28
+ rescue StandardError => ex
29
+ raise WrappableError, ex
30
+ end
31
+ end
32
+ end
33
+ assert_equal(5, tries)
34
+ end
35
+ # rubocop:enable all
36
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msmg_public
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-07 00:00:00.000000000 Z
11
+ date: 2018-04-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: MSM pubicly available Ruby
14
14
  email:
@@ -24,6 +24,7 @@ files:
24
24
  - lib/comparable_by_attr.rb
25
25
  - lib/dig.rb
26
26
  - lib/to_hash.rb
27
+ - lib/with_retries.rb
27
28
  - msmg_public.gemspec
28
29
  - readme.md
29
30
  - test/test_helper.rb
@@ -31,6 +32,7 @@ files:
31
32
  - test/unit/test_comparable_by_attr.rb
32
33
  - test/unit/test_dig.rb
33
34
  - test/unit/test_to_hash.rb
35
+ - test/unit/test_with_retries.rb
34
36
  homepage: https://github.com/MSMFG/msmg_ruby-public
35
37
  licenses:
36
38
  - Apache-2.0