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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/bogo/lazy.rb +2 -2
- data/lib/bogo/retry.rb +205 -0
- data/lib/bogo/version.rb +1 -1
- data/lib/bogo.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c174f6ad37a9e19f3dfe03122c33a495806dccb3
|
4
|
+
data.tar.gz: 3912483719bc84e6af89542580c05dd45aaef600
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fac9b5a22d68c59244e2285812eb78eddab548692b61cae3bc249df04a9ea551a2392c99be411589b5bdbed39bc91118c10eedd7f761f8c80959ad22db88b3a
|
7
|
+
data.tar.gz: b56a8eac111a44ad7d71eefa03cfdf79a8ff652f2b976e958da93d57faca47877cb1d9edc20df87157114c096d1842f5c9db14e830ddb539e9a7bc94a919f1f6
|
data/CHANGELOG.md
CHANGED
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
|
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
data/lib/bogo.rb
CHANGED
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.
|
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-
|
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:
|