data/.travis.yml CHANGED
@@ -1,5 +1,4 @@
1
1
language: ruby
2
- script: ruby -Ilib -Itest test/exponential_backoff_test.rb
3
2
rvm:
4
3
- 1.9.3
5
4
- 1.9.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ 0.0.2
2
+
3
+ - Initialize backoff with Array or Range as a convenience.
4
+ - Check if given iteration is one of intervals when running in a loop.
5
+
6
+ 0.0.1
7
+
8
+ - Initial version.
data/README.md CHANGED
@@ -38,6 +38,13 @@ maximal_elapsed_time = 60.0
38
38
backoff = ExponentialBackoff.new(minimal_interval, maximal_elapsed_time)
39
39
```
40
40
41
+ Arrays and ranges work for your convenience too:
42
+
43
+ ```ruby
44
+ backoff = ExponentialBackoff.new(minimal_interval..maximal_elapsed_time)
45
+ backoff = ExponentialBackoff.new([minimal_interval, maximal_elapsed_time])
46
+ ```
47
+
41
48
You can get intervals for specified range:
42
49
43
50
```ruby
@@ -94,6 +101,15 @@ You can peek what is the current interval:
94
101
backoff.current_interval # 3.764
95
102
```
96
103
104
+ You can check if given iteration is one of intervals or maximum interval multiple:
105
+
106
+ ```ruby
107
+ backoff = ExponentialBackoff.new(1, 10)
108
+ backoff.iteration_active?(4) # true
109
+ backoff.iteration_active?(20) # true
110
+ backoff.iteration_active?(3) # false
111
+ ```
112
+
97
113
There is also sugar for executing block of code until successful with increasing intervals:
98
114
99
115
```ruby
@@ -111,7 +127,7 @@ end
111
127
Running tests
112
128
-------------
113
129
114
- ruby -Ilib -Itest test/exponential_backoff_test.rb
130
+ bundle exec rake test
115
131
116
132
117
133
Supported rubies
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
#!/usr/bin/env rake
2
2
require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.pattern = "test/*_test.rb"
7
+ end
8
+
9
+ desc "Run tests"
10
+ task :default => :test
data/exponential-backoff.gemspec CHANGED
@@ -13,4 +13,6 @@ Gem::Specification.new do |gem|
13
13
gem.name = "exponential-backoff"
14
14
gem.require_paths = ["lib"]
15
15
gem.version = ExponentialBackoff::VERSION
16
+
17
+ gem.add_development_dependency 'rake'
16
18
end
data/lib/exponential_backoff.rb CHANGED
@@ -4,9 +4,14 @@ class ExponentialBackoff
4
4
attr_accessor :multiplier, :randomize_factor
5
5
attr_reader :current_interval
6
6
7
- def initialize(minimal_interval, maximum_elapsed_time)
8
- @maximum_elapsed_time = maximum_elapsed_time
9
- @minimal_interval = minimal_interval
7
+ def initialize(interval, maximum_elapsed_time = nil)
8
+ if interval.respond_to?(:first)
9
+ @minimal_interval, @maximum_elapsed_time = interval.first, interval.last
10
+ else
11
+ @minimal_interval, @maximum_elapsed_time = interval, maximum_elapsed_time
12
+ end
13
+ raise ArgumentError, "Invalid range specified" if [@minimal_interval, @maximum_elapsed_time].any? { |i| !i.is_a?(Numeric) }
14
+
10
15
@randomize_factor = 0
11
16
@multiplier = 2.0
12
17
clear
@@ -20,6 +25,16 @@ class ExponentialBackoff
20
25
@current_interval = @enumerator.next
21
26
end
22
27
28
+ def iteration_active?(iteration)
29
+ index = 0
30
+ current_interval = interval_at(index)
31
+ while current_interval < iteration && current_interval < @maximum_elapsed_time
32
+ index += 1
33
+ current_interval = interval_at(index)
34
+ end
35
+ current_interval == iteration || iteration % @maximum_elapsed_time == 0
36
+ end
37
+
23
38
def intervals_for(range)
24
39
range.to_a.map { |iteration| interval_at(iteration) }
25
40
end
data/lib/exponential_backoff/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
class ExponentialBackoff
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
end
data/test/exponential_backoff_test.rb CHANGED
@@ -2,6 +2,22 @@ require 'test/unit'
2
2
require 'exponential_backoff'
3
3
4
4
class ExponentialBackoffTest < Test::Unit::TestCase
5
+ def test_range_initializer
6
+ backoff = ExponentialBackoff.new(1..5)
7
+ assert_equal [1, 2, 4, 5], backoff.intervals_for(0..3)
8
+ end
9
+
10
+ def test_array_initializer
11
+ backoff = ExponentialBackoff.new([1, 5])
12
+ assert_equal [1, 2, 4, 5], backoff.intervals_for(0..3)
13
+ end
14
+
15
+ def test_no_maximal_time
16
+ assert_raise ArgumentError do
17
+ backoff = ExponentialBackoff.new(2)
18
+ end
19
+ end
20
+
5
21
def test_multiplier_default
6
22
min, max = 1, 2
7
23
backoff = ExponentialBackoff.new(min, max)
@@ -154,5 +170,20 @@ class ExponentialBackoffTest < Test::Unit::TestCase
154
170
elapsed = Time.now.to_f - time
155
171
assert elapsed >= 0.3
156
172
end
173
+
174
+ def test_iteration_active_for_one_from_list
175
+ backoff = ExponentialBackoff.new(1, 10)
176
+ assert backoff.iteration_active?(4)
177
+ end
178
+
179
+ def test_iteration_active_for_maximum_interval_multiple
180
+ backoff = ExponentialBackoff.new(1, 10)
181
+ assert backoff.iteration_active?(20)
182
+ end
183
+
184
+ def test_iteration_active_for_not_from_list_and_not_multiple
185
+ backoff = ExponentialBackoff.new(1, 10)
186
+ refute backoff.iteration_active?(6)
187
+ end
157
188
end
158
189
metadata CHANGED
@@ -1,16 +1,32 @@
1
1
--- !ruby/object:Gem::Specification
2
2
name: exponential-backoff
3
3
version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
4
prerelease:
5
+ version: 0.0.2
6
6
platform: ruby
7
7
authors:
8
8
- Paweł Pacana
9
9
autorequire:
10
10
bindir: bin
11
11
cert_chain: []
12
- date: 2012-09-26 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-01-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ none: false
21
+ prerelease: false
22
+ name: rake
23
+ requirement: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ! '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ none: false
29
+ type: :development
14
30
description:
15
31
email:
16
32
- pawel.pacana@gmail.com
@@ -20,6 +36,7 @@ extra_rdoc_files: []
20
36
files:
21
37
- .gitignore
22
38
- .travis.yml
39
+ - CHANGELOG.md
23
40
- Gemfile
24
41
- LICENSE
25
42
- README.md
@@ -35,23 +52,28 @@ rdoc_options: []
35
52
require_paths:
36
53
- lib
37
54
required_ruby_version: !ruby/object:Gem::Requirement
38
- none: false
39
55
requirements:
40
56
- - ! '>='
41
57
- !ruby/object:Gem::Version
42
58
version: '0'
43
- required_rubygems_version: !ruby/object:Gem::Requirement
59
+ segments:
60
+ - 0
61
+ hash: 4010949273159976482
44
62
none: false
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
64
requirements:
46
65
- - ! '>='
47
66
- !ruby/object:Gem::Version
48
67
version: '0'
68
+ segments:
69
+ - 0
70
+ hash: 4010949273159976482
71
+ none: false
49
72
requirements: []
50
73
rubyforge_project:
51
- rubygems_version: 1.8.23
74
+ rubygems_version: 1.8.24
52
75
signing_key:
53
76
specification_version: 3
54
77
summary: Exponential backoff algorithm for better reconnect intervals.
55
78
test_files:
56
79
- test/exponential_backoff_test.rb
57
- has_rdoc: