retry_upto 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog.md ADDED
@@ -0,0 +1,5 @@
1
+ # retry_upto changelog
2
+
3
+ ## v1.0
4
+
5
+ First version
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2011 Raul Murciano, Glenn Gillen, Pedro Belo,
2
+ Jaime Iniesta, Lleïr Borras and Aitor García Rey.
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # retry_upto: retry with steroids
2
+
3
+ ## Usage
4
+
5
+ Basic usage
6
+
7
+ - retries up to 5 times catching any exception, doesn't wait between attempts:
8
+
9
+ retry_upto(5) do ... end
10
+
11
+ Waiting time between attempts
12
+
13
+ - retries up to 5 times, waits 2 seconds between attempts:
14
+
15
+ retry_upto(5, :interval => 2) do ... end
16
+
17
+ Varying waiting time between attempts
18
+
19
+ - retries up to 5 times, waits 1 second after the first attempt and increases
20
+ the time between the following attempts (2, 4, 8, ...):
21
+
22
+ retry_upto(5, :interval => 1, :growth => 2) do ... end
23
+
24
+ - retries up to 5 times, waits 1 second after the first attempt and decreases
25
+ the time between the following attempts (0.5, 0.25, 0.125, ...):
26
+
27
+ retry_upto(5, :interval => 1, :growth => 0.5) do ... end
28
+
29
+ - retries up to 5 times, waits 1 second after the first attempt and increases
30
+ randomly the time between the following attempts:
31
+
32
+ retry_upto(5, :interval => 1, :growth => lambda{ |x| x + rand(3) } ) do ... end
33
+
34
+ Retrying only when certain Exceptions get raised
35
+
36
+ - retries up to 5 times only after a ZeroDivisionError, raising any other Exception:
37
+
38
+ retry_upto(5, :rescue => ZeroDivisionError) do ... end
39
+
40
+ All the options described above can be combined together.
41
+
42
+ ## License
43
+
44
+ See the LICENSE file included in the distribution.
45
+
46
+ ## Authors
47
+
48
+ This gem was born from gists by Raul Murciano, Glenn Gillen, Pedro Belo, Jaime Iniesta, Lleïr Borras and ideas taken from Aitor García Rey.
49
+
50
+ Yes, so many brain cells and so few lines of code. Great, isn't it?
51
+
data/RakeFile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ task :default => [:test]
5
+
6
+ desc 'Run tests'
7
+ Rake::TestTask.new('test') do |t|
8
+ t.pattern = 'test/*_test.rb'
9
+ t.verbose = true
10
+ t.warning = true
11
+ end
data/lib/retry_upto.rb ADDED
@@ -0,0 +1,70 @@
1
+ # retry with steroids
2
+ #
3
+ # Basic usage:
4
+ #
5
+ # - retries up to 5 times catching any exception, doesn't wait between attempts
6
+ #
7
+ # retry_upto(5) do ... end
8
+ #
9
+ #
10
+ # Waiting time between attempts:
11
+ #
12
+ # - retries up to 5 times, waits 2 seconds between attempts
13
+ #
14
+ # retry_upto(5, :interval => 2) do ... end
15
+ #
16
+ #
17
+ # Varying waiting time between attempts:
18
+ #
19
+ # - retries up to 5 times, waits 1 second after the first attempt and increases
20
+ # the time between the following attempts (2, 4, 8, ...)
21
+ #
22
+ # retry_upto(5, :interval => 1, :growth => 2) do ... end
23
+ #
24
+ # - retries up to 5 times, waits 1 second after the first attempt and decreases
25
+ # the time between the following attempts (0.5, 0.25, 0.125, ...)
26
+ #
27
+ # retry_upto(5, :interval => 1, :growth => 0.5) do ... end
28
+ #
29
+ # - retries up to 5 times, waits 1 second after the first attempt and increases
30
+ # randomly the time between the following attempts
31
+ #
32
+ # retry_upto(5, :interval => 1, :growth => lambda{ |x| x + rand(3) } ) do ... end
33
+ #
34
+ #
35
+ # Retrying only when certain Exceptions get raised:
36
+ #
37
+ # - retries up to 5 times only after a ZeroDivisionError, raising any other Exception
38
+ #
39
+ # retry_upto(5, :rescue => ZeroDivisionError) do ... end
40
+ #
41
+ #
42
+ # All the described options can be combined together.
43
+
44
+ def retry_upto(max_retries = 1, options = {})
45
+ yield
46
+ rescue (options[:rescue] || Exception)
47
+ raise if (max_retries -= 1) == 0
48
+ sleep(options[:interval] || 0)
49
+ if options[:growth].respond_to?('*')
50
+ options[:interval] = options[:interval] * options[:growth]
51
+ elsif options[:growth].respond_to?(:call)
52
+ options[:interval] = options[:growth].call(options[:interval])
53
+ end
54
+ retry
55
+ end
56
+
57
+
58
+
59
+ # Extends enumerator to allow usage like:
60
+ #
61
+ # 5.times.retry do
62
+ # ...
63
+ # end
64
+ #
65
+
66
+ class Enumerator
67
+ def retry(options = {}, &blk)
68
+ retry_upto(self.count, options, &blk)
69
+ end
70
+ end
@@ -0,0 +1,92 @@
1
+ require './test/test_helper'
2
+
3
+ class Retry_uptoTest < MiniTest::Unit::TestCase
4
+
5
+ class FooError < Exception; end
6
+
7
+ # raises ZeroDivisionError in the two first hits
8
+ class Target
9
+ attr_accessor :hits
10
+ def initialize; @hits = 0; end
11
+
12
+ def hit!
13
+ @hits += 1
14
+ raise FooError if @hits < 3
15
+ end
16
+ end
17
+
18
+ def setup
19
+ @target = Target.new
20
+ end
21
+
22
+ # number of attempts
23
+
24
+ def test_retries_one_time_by_default_without_capturing_the_exception
25
+ assert_raises(FooError) do
26
+ retry_upto{ @target.hit! }
27
+ end
28
+ assert_equal 1, @target.hits
29
+ end
30
+
31
+ def test_retries_the_desired_number_of_attempts
32
+ retry_upto(3){ @target.hit! }
33
+ assert_equal 3, @target.hits
34
+ end
35
+
36
+ # interval between attempts
37
+
38
+ def test_there_is_no_interval_between_attempts_by_default
39
+ self.expects(:sleep).times(2).with(0).returns(nil)
40
+ retry_upto(3){ @target.hit! }
41
+ end
42
+
43
+ def test_interval_between_attempts_can_be_customized
44
+ self.expects(:sleep).times(2).with(5).returns(nil)
45
+ retry_upto(3, :interval => 5){ @target.hit! }
46
+ end
47
+
48
+ # interval growth between attempts
49
+
50
+ def test_inverval_can_be_multiplied_by_an_integer_growth
51
+ self.expects(:sleep).times(1).with(5)
52
+ self.expects(:sleep).times(1).with(15)
53
+ retry_upto(3, :interval => 5, :growth => 3){ @target.hit! }
54
+ end
55
+
56
+ def test_grow_for_inverval_between_attempts_can_be_defined_with_a_lambda
57
+ self.expects(:sleep).times(1).with(5)
58
+ self.expects(:sleep).times(1).with(7)
59
+ retry_upto(3, :interval => 5, :growth => lambda{ |t| t + 2 }){ @target.hit! }
60
+ end
61
+
62
+ # exceptions
63
+
64
+ def test_by_default_any_exception_gets_captured_if_there_are_attempts_left
65
+ retry_upto(3){ @target.hit! }
66
+ assert true # if we reach this no exception was raised out of retry_upto
67
+ end
68
+
69
+ def test_the_last_attempt_does_not_capture_the_exception
70
+ assert_raises(FooError) do
71
+ retry_upto(2){ @target.hit! }
72
+ end
73
+ end
74
+
75
+ def test_a_specified_exception_will_be_captured_between_attempts
76
+ retry_upto(3, :rescue => FooError){ @target.hit! }
77
+ assert true # if we reach this no exception was raised out of retry_upto
78
+ end
79
+
80
+ def test_the_last_attempt_does_not_capture_the_specified_exception
81
+ assert_raises(FooError) do
82
+ retry_upto(2, :rescue => FooError){ @target.hit! }
83
+ end
84
+ end
85
+
86
+ def test_a_exception_different_from_the_specified_one_will_not_be_captured_between_attempts
87
+ assert_raises(FooError) do
88
+ retry_upto(3, :rescue => ZeroDivisionError){ @target.hit! }
89
+ end
90
+ end
91
+
92
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+ require 'mocha'
4
+ require './lib/retry_upto'
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: retry_upto
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ version: "1.0"
10
+ platform: ruby
11
+ authors:
12
+ - Raul Murciano
13
+ - Glenn Gillen
14
+ - Pedro Belo
15
+ - Jaime Iniesta
16
+ - "Lle\xC3\xAFr Borras"
17
+ - "Aitor Garc\xC3\xADa Rey"
18
+ autorequire:
19
+ bindir: bin
20
+ cert_chain: []
21
+
22
+ date: 2011-10-07 00:00:00 -07:00
23
+ default_executable:
24
+ dependencies:
25
+ - !ruby/object:Gem::Dependency
26
+ name: minitest
27
+ prerelease: false
28
+ requirement: &id001 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ">"
32
+ - !ruby/object:Gem::Version
33
+ hash: 3
34
+ segments:
35
+ - 2
36
+ - 0
37
+ version: "2.0"
38
+ type: :development
39
+ version_requirements: *id001
40
+ - !ruby/object:Gem::Dependency
41
+ name: mocha
42
+ prerelease: false
43
+ requirement: &id002 !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ hash: 55
49
+ segments:
50
+ - 0
51
+ - 10
52
+ - 0
53
+ version: 0.10.0
54
+ type: :development
55
+ version_requirements: *id002
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ prerelease: false
59
+ requirement: &id003 !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 63
65
+ segments:
66
+ - 0
67
+ - 9
68
+ - 2
69
+ version: 0.9.2
70
+ type: :development
71
+ version_requirements: *id003
72
+ description: adds some useful options to retry code blocks
73
+ email:
74
+ - raul@murciano.net
75
+ executables: []
76
+
77
+ extensions: []
78
+
79
+ extra_rdoc_files: []
80
+
81
+ files:
82
+ - lib/retry_upto.rb
83
+ - test/retry_upto_test.rb
84
+ - test/test_helper.rb
85
+ - Changelog.md
86
+ - Gemfile
87
+ - LICENSE
88
+ - RakeFile
89
+ - README.md
90
+ has_rdoc: true
91
+ homepage: http://github.com/raul/retry_upto
92
+ licenses: []
93
+
94
+ post_install_message:
95
+ rdoc_options: []
96
+
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ hash: 3
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ requirements: []
118
+
119
+ rubyforge_project: retry_upto
120
+ rubygems_version: 1.5.2
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: retry with steroids
124
+ test_files: []
125
+