bogo 0.1.26 → 0.1.28

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: f7e400810bf3504865b80afad6d8382992d174ee
4
- data.tar.gz: 975826f4297df7023982b96d0c5807dff072b0d0
3
+ metadata.gz: c174f6ad37a9e19f3dfe03122c33a495806dccb3
4
+ data.tar.gz: 3912483719bc84e6af89542580c05dd45aaef600
5
5
  SHA512:
6
- metadata.gz: c8e162b1c52619ab538c1ac3e64f954738f0d646e04acd6fc7403762b68d79f4b938c6e98c78383ac53cf1c629e332ac5f315135a564063734e408bc9e295831
7
- data.tar.gz: 9eee1d3be0b4219b9bd9713f6c693256f99e310476db4714687f7499272bb4e8c24d39da4305c5bedb196b931dc46fa418c03c82b5c4ccd0fe3a456aec4231e2
6
+ metadata.gz: 0fac9b5a22d68c59244e2285812eb78eddab548692b61cae3bc249df04a9ea551a2392c99be411589b5bdbed39bc91118c10eedd7f761f8c80959ad22db88b3a
7
+ data.tar.gz: b56a8eac111a44ad7d71eefa03cfdf79a8ff652f2b976e958da93d57faca47877cb1d9edc20df87157114c096d1842f5c9db14e830ddb539e9a7bc94a919f1f6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## v0.1.28
2
+ * [Smash] Ensure valid data type on checksum generation
3
+ * [Retry] Add new retry abstract and concrete subclasses
4
+
1
5
  ## v0.1.26
2
6
  * [Smash] Fix behavior around accessing falsey values
3
7
 
data/lib/bogo/lazy.rb CHANGED
@@ -67,7 +67,7 @@ module Bogo
67
67
  def valid_state
68
68
  data.merge!(dirty)
69
69
  dirty.clear
70
- @_checksum = Digest::SHA256.hexdigest(MultiJson.dump(data))
70
+ @_checksum = Digest::SHA256.hexdigest(MultiJson.dump(data).to_s)
71
71
  self
72
72
  end
73
73
 
@@ -106,7 +106,7 @@ module Bogo
106
106
  # Disable dirty state
107
107
  def always_clean!
108
108
  self.class_eval do
109
- def dirty?; false; end
109
+ def dirty?(*args); false; end
110
110
  def valid_state; self; end
111
111
  alias_method :dirty, :data
112
112
  end
data/lib/bogo/retry.rb ADDED
@@ -0,0 +1,205 @@
1
+ require 'bogo'
2
+
3
+ module Bogo
4
+
5
+ # Perform action and retry until successful or abort
6
+ class Retry
7
+
8
+ # Create a type of retry
9
+ #
10
+ # @param type [String, Symbol] name of retry type
11
+ # @param args [Object] instantiation arguments
12
+ # @yield instantiation block
13
+ # @return [Retry] specific subclass instance
14
+ def self.build(type, *args, &block)
15
+ klass = self.const_get(Bogo::Utility.camel(type))
16
+ klass.new(*args, &block)
17
+ end
18
+
19
+ # @return [Proc] action to perform
20
+ attr_reader :action
21
+ # @return [Integer] number of attempts
22
+ attr_reader :attempts
23
+ # @return [TrueClass, FalseClass] retry is dead
24
+ attr_reader :dead
25
+ # @return [String] description of action
26
+ attr_reader :description
27
+ # @return [Integer] maximum number of attempts
28
+ attr_reader :max_attempts
29
+ # @return [Bogo::Ui] UI to direct warnings
30
+ attr_reader :ui
31
+
32
+ # Create a new retry instance
33
+ #
34
+ # @param args [Hash]
35
+ # @option args [String] :description action description
36
+ # @option args [Bogo::Ui] :ui output failure/retry notifications
37
+ # @option args [Integer] :max_attempts maximum number of retries
38
+ # @return [self]
39
+ def initialize(args={}, &block)
40
+ unless(block)
41
+ raise ArgumentError.new 'Expecting block but no block was provided!'
42
+ end
43
+ args = args.to_smash
44
+ @ui = args[:ui]
45
+ @description = args.fetch(:description, 'Task')
46
+ @max_attempts = args[:max_attempts]
47
+ @action = block
48
+ @attempts = 0
49
+ @dead = false
50
+ run! unless args[:auto_run] == false
51
+ end
52
+
53
+ # Run action until success
54
+ #
55
+ # return [Object] result of action
56
+ def run!
57
+ if(dead)
58
+ raise RuntimeError.new "Action has already reached maximum allowed attempts (#{max_attempts})!"
59
+ else
60
+ begin
61
+ log_attempt!
62
+ action.call
63
+ rescue => e
64
+ if(max_attempts.nil? || attempts < max_attempts)
65
+ interval = wait_on_failure(e)
66
+ if(ui)
67
+ if(max_attempts)
68
+ attempt_info = "[Attempt #{attempts}/#{max_attempts}]"
69
+ end
70
+ ui.warn "#{description} failed (#{e.class}: #{e}) - Retry in #{interval.to_i} seconds #{attempt_info}"
71
+ end
72
+ sleep(interval)
73
+ retry
74
+ else
75
+ if(ui)
76
+ ui.error "#{description} failed (#{e.class}: #{e}) - Maximum number of attempts reached!"
77
+ end
78
+ @dead = true
79
+ raise e
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ # @return [Integer]
86
+ def retries
87
+ attempts > 0 ? attempts - 1 : 0
88
+ end
89
+
90
+ protected
91
+
92
+ # Amount of time to wait
93
+ #
94
+ # @param error [StandardError] failure exception
95
+ # @return [Numeric] amount of wait time
96
+ def wait_on_failure(error)
97
+ raise NotImplementedError
98
+ end
99
+
100
+ # @return [Intenger]
101
+ def log_attempt!
102
+ @attempts = attempts.next
103
+ end
104
+
105
+ # Flat retry implementation
106
+ class Flat < Retry
107
+
108
+ # @return [Numeric]
109
+ attr_reader :wait_interval
110
+
111
+ # Create a new flat retry instance
112
+ #
113
+ # @param args [Hash]
114
+ # @option args [Numeric] :wait_interval Defaults to 5 seconds
115
+ # @return [self]
116
+ def initialize(args={}, &block)
117
+ @wait_interval = args[:wait_interval].to_f
118
+ unless(@wait_interval > 0)
119
+ @wait_interval = 5
120
+ end
121
+ super
122
+ end
123
+
124
+ protected
125
+
126
+ # @return [Numeric] wait time
127
+ def wait_on_failure(*_)
128
+ wait_interval
129
+ end
130
+
131
+ end
132
+
133
+ # Linear retry implementation
134
+ class Linear < Retry
135
+
136
+ # @return [Numeric]
137
+ attr_reader :wait_interval
138
+ # @return [Numeric]
139
+ attr_reader :wait_multiplier
140
+
141
+ # Create a new linear retry instance
142
+ #
143
+ # @param args [Hash]
144
+ # @option args [Numeric] :wait_interval Defaults to 5 seconds
145
+ # @option args [Numeric] :wait_multiplier Defaults to 2
146
+ # @return [self]
147
+ def initialize(args={}, &block)
148
+ @wait_interval = args[:wait_interval].to_f
149
+ @wait_multiplier = args[:wait_multiplier].to_f
150
+ unless(@wait_interval > 0)
151
+ @wait_interval = 5
152
+ end
153
+ unless(@wait_multiplier > 0)
154
+ @wait_multiplier = 2
155
+ end
156
+ super
157
+ end
158
+
159
+ protected
160
+
161
+ # @return [Numeric] wait time
162
+ def wait_on_failure(*_)
163
+ wait_interval * attempts
164
+ end
165
+
166
+ end
167
+
168
+ # Exponential retry implementation
169
+ class Exponential < Retry
170
+
171
+ # @return [Numeric]
172
+ attr_reader :wait_interval
173
+ # @return [Numeric]
174
+ attr_reader :wait_exponent
175
+
176
+ # Create a new linear retry instance
177
+ #
178
+ # @param args [Hash]
179
+ # @option args [Numeric] :wait_interval Defaults to 5 seconds
180
+ # @option args [Numeric] :wait_exponent Defaults to 2
181
+ # @return [self]
182
+ def initialize(args={}, &block)
183
+ @wait_interval = args[:wait_interval].to_f
184
+ @wait_exponent = args[:wait_exponent].to_f
185
+ unless(@wait_interval > 0)
186
+ @wait_interval = 5
187
+ end
188
+ unless(@wait_exponent > 0)
189
+ @wait_exponent = 2
190
+ end
191
+ super
192
+ end
193
+
194
+ protected
195
+
196
+ # @return [Numeric] wait time
197
+ def wait_on_failure(*_)
198
+ retries == 0 ? wait_interval : (wait_interval + retries) ** wait_exponent
199
+ end
200
+
201
+ end
202
+
203
+ end
204
+
205
+ end
data/lib/bogo/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Bogo
2
2
  # Current library version
3
- VERSION = Gem::Version.new('0.1.26')
3
+ VERSION = Gem::Version.new('0.1.28')
4
4
  end
data/lib/bogo.rb CHANGED
@@ -7,6 +7,7 @@ module Bogo
7
7
  autoload :Lazy, 'bogo/lazy'
8
8
  autoload :Memoization, 'bogo/memoization'
9
9
  autoload :PriorityQueue, 'bogo/priority_queue'
10
+ autoload :Retry, 'bogo/retry'
10
11
  autoload :Smash, 'bogo/smash'
11
12
  autoload :Utility, 'bogo/utility'
12
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bogo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.26
4
+ version: 0.1.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-22 00:00:00.000000000 Z
11
+ date: 2015-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -85,6 +85,7 @@ files:
85
85
  - lib/bogo/lazy.rb
86
86
  - lib/bogo/memoization.rb
87
87
  - lib/bogo/priority_queue.rb
88
+ - lib/bogo/retry.rb
88
89
  - lib/bogo/smash.rb
89
90
  - lib/bogo/utility.rb
90
91
  - lib/bogo/version.rb
@@ -113,3 +114,4 @@ signing_key:
113
114
  specification_version: 4
114
115
  summary: Helper libraries
115
116
  test_files: []
117
+ has_rdoc: