attempt 0.1.0 → 0.1.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.
Files changed (7) hide show
  1. data/CHANGES +7 -2
  2. data/MANIFEST +7 -9
  3. data/README +61 -64
  4. data/Rakefile +20 -0
  5. data/lib/attempt.rb +105 -99
  6. data/test/tc_attempt.rb +40 -42
  7. metadata +6 -5
data/CHANGES CHANGED
@@ -1,2 +1,7 @@
1
- == 0.1.0 - 9-Jun-2006
2
- * Initial commit
1
+ == 0.1.1 - 31-Jul-2007
2
+ * Added a Rakefile with tasks for testing and installation.
3
+ * Removed the install.rb file, since installation is now handled by the Rakefile.
4
+ * Some minor doc updates.
5
+
6
+ == 0.1.0 - 9-Jun-2006
7
+ * Initial commit
data/MANIFEST CHANGED
@@ -1,9 +1,7 @@
1
- CHANGES
2
- MANIFEST
3
- README
4
- install.rb
5
- attempt.gemspec
6
-
7
- lib/attempt.rb
8
-
9
- test/tc_attempt.rb
1
+ * CHANGES
2
+ * MANIFEST
3
+ * README
4
+ * Rakefile
5
+ * attempt.gemspec
6
+ * lib/attempt.rb
7
+ * test/tc_attempt.rb
data/README CHANGED
@@ -1,64 +1,61 @@
1
- == Description
2
- A thin wrapper for begin + rescue + sleep + retry.
3
-
4
- == Prerequisites
5
- Ruby 1.8.0 or later.
6
-
7
- == Installation
8
- === Standard Installation
9
- ruby test/tc_attempt.rb
10
- ruby install.rb
11
-
12
- === Gem Installation
13
- ruby test/tc_attempt.rb
14
- ruby attempt.gemspec
15
- gem install attempt-x-y-z.gem # Where x-y-z is a version
16
-
17
- == Synopsis
18
- require 'attempt'
19
-
20
- # Attempt to ftp to some host, trying 3 times with 30 seconds between
21
- # attempts before finally raising an error.
22
- #
23
- attempt(3, 30){
24
- Net::FTP.open(host, user, passwd){ ... }
25
- }
26
-
27
- # Or, do things the long way...
28
- code = Attempt.new{ |a|
29
- a.tries = 3
30
- a.interval = 30
31
- }
32
-
33
- code.attempt{
34
- Net::FTP.open(host, user, passwd){ ... }
35
- }
36
-
37
- == Future Plans
38
- Add the ability to set an absolute maximum number of seconds to prevent
39
- nested sleep/retry from delaying attempts longer than expected.
40
-
41
- == Known Bugs
42
- None that I'm aware of. If you find any bugs, please log them on the
43
- project page at http://www.rubyforge.org/projects/shards.
44
-
45
- == Notes From the Author
46
- Use with caution. Specifically, make sure you aren't inadvertantly
47
- wrapping code that already performs sleep + retry. Otherwise, you'll
48
- end up with a series of nested retry's that could take much longer to
49
- work than you expect.
50
-
51
- == Warranty
52
- This package is provided "as is" and without any express or
53
- implied warranties, including, without limitation, the implied
54
- warranties of merchantability and fitness for a particular purpose.
55
-
56
- == License
57
- Ruby's
58
-
59
- == Copyright
60
- (C) 2006, Daniel J. Berger
61
- All Rights Reserved
62
-
63
- == Author
64
- Daniel J. Berger
1
+ == Description
2
+ A thin wrapper for begin + rescue + sleep + retry.
3
+
4
+ == Prerequisites
5
+ Ruby 1.8.0 or later.
6
+
7
+ == Installation
8
+ rake test (optional)
9
+ rake install (non-gem) or rake install_gem (gem)
10
+
11
+ == Synopsis
12
+ require 'attempt'
13
+
14
+ # Attempt to ftp to some host, trying 3 times with 30 seconds between
15
+ # attempts before finally raising an error.
16
+ #
17
+ attempt(3, 30){
18
+ Net::FTP.open(host, user, passwd){ ... }
19
+ }
20
+
21
+ # Or, do things the long way...
22
+ code = Attempt.new{ |a|
23
+ a.tries = 3
24
+ a.interval = 30
25
+ }
26
+
27
+ code.attempt{
28
+ Net::FTP.open(host, user, passwd){ ... }
29
+ }
30
+
31
+ == Future Plans
32
+ Add the ability to set an absolute maximum number of seconds to prevent
33
+ nested sleep/retry from delaying attempts longer than expected.
34
+
35
+ == Known Bugs
36
+ None that I'm aware of. If you find any bugs, please log them on the
37
+ project page at http://www.rubyforge.org/projects/shards.
38
+
39
+ == Notes From the Author
40
+ Use with caution. Specifically, make sure you aren't inadvertantly
41
+ wrapping code that already performs sleep + retry. Otherwise, you'll
42
+ end up with a series of nested retry's that could take much longer to
43
+ work than you expect.
44
+
45
+ == Acknowledgements
46
+ This library is partially based on Mark Fowler's 'Attempt' Perl module.
47
+
48
+ == Warranty
49
+ This package is provided "as is" and without any express or
50
+ implied warranties, including, without limitation, the implied
51
+ warranties of merchantability and fitness for a particular purpose.
52
+
53
+ == License
54
+ Ruby's
55
+
56
+ == Copyright
57
+ (C) 2006-2007, Daniel J. Berger
58
+ All Rights Reserved
59
+
60
+ == Author
61
+ Daniel J. Berger
@@ -0,0 +1,20 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ desc "Install the attempt package (non-gem)"
5
+ task :install do
6
+ cp 'lib/attempt.rb', Config::CONFIG['sitelibdir'], :verbose => true
7
+ end
8
+
9
+ desc "Install the attempt package as a gem"
10
+ task :install_gem do
11
+ ruby 'attempt.gemspec'
12
+ file = Dir["*.gem"].first
13
+ sh "gem install #{file}"
14
+ end
15
+
16
+ Rake::TestTask.new do |t|
17
+ t.libs << 'lib'
18
+ t.warning = true
19
+ t.test_files = FileList['test/tc*']
20
+ end
@@ -1,99 +1,105 @@
1
- require 'timeout'
2
-
3
- class Attempt
4
- VERSION = '0.1.0'
5
-
6
- # Number of attempts to make before failing. The default is 3.
7
- attr_accessor :tries
8
-
9
- # Number of seconds to wait between attempts. The default is 60.
10
- attr_accessor :interval
11
-
12
- # A boolean value that determines whether errors that would have been
13
- # raised should be sent to STDERR as warnings. The default is true.
14
- attr_accessor :warnings
15
-
16
- # If you provide an IO handle to this option then errors that would
17
- # have been raised are sent to that handle.
18
- attr_accessor :log
19
-
20
- # If set, this increments the interval with each failed attempt by that
21
- # number of seconds.
22
- attr_accessor :increment
23
-
24
- # If set, the code block is further wrapped in a timeout block.
25
- attr_accessor :timeout
26
-
27
- # Determines which exception level to check when looking for errors to
28
- # retry. The default is 'Exception' (i.e. all errors).
29
- attr_accessor :level
30
-
31
- # :call-seq:
32
- # Attempt.new{ |a| ... }
33
- #
34
- # Creates and returns a new +Attempt+ object. Use a block to set the
35
- # accessors.
36
- #
37
- def initialize
38
- @tries = 3 # Reasonable default
39
- @interval = 60 # Reasonable default
40
- @log = nil # Should be an IO handle, if provided
41
- @increment = nil # Should be an int, if provided
42
- @timeout = nil # Wrap the code in a timeout block if provided
43
- @level = Exception # Level of exception to be caught
44
- @warnings = true # Errors sent to STDERR as warnings if true
45
-
46
- yield self if block_given?
47
- end
48
-
49
- def attempt
50
- count = 1
51
- begin
52
- if @timeout
53
- Timeout.timeout(@timeout){ yield }
54
- else
55
- yield
56
- end
57
- rescue @level => error
58
- @tries -= 1
59
- if @tries > 0
60
- msg = "Error on attempt # #{count}: #{error}; retrying"
61
- count += 1
62
- warn msg if @warnings
63
- @log.puts msg if @log
64
- @interval += @increment if @increment
65
- sleep @interval
66
- retry
67
- end
68
- raise
69
- end
70
- end
71
- end
72
-
73
- module Kernel
74
- # attempt(tries = 3, interval = 60, timeout = nil){ # some op }
75
- #
76
- # Attempt to perform the operation in the provided block up to +tries+
77
- # times, sleeping +interval+ between each try. By default the number
78
- # of tries defaults to 3, the interval defaults to 60 seconds, and there
79
- # is no timeout specified.
80
- #
81
- # If +timeout+ is provided then the operation is wrapped in a Timeout
82
- # block as well. This is handy for those rare occasions when an IO
83
- # connection could hang indefinitely, for example.
84
- #
85
- # If the operation still fails the (last) error is then re-raised.
86
- #
87
- # This is really just a wrapper for Attempt.new where the simple case is
88
- # good enough i.e. you don't care about warnings, increments or logging,
89
- # and you want a little added convenience.
90
- #
91
- def attempt(tries = 3, interval = 60, timeout = nil, &block)
92
- raise 'no block given' unless block_given?
93
- Attempt.new{ |a|
94
- a.tries = tries
95
- a.interval = interval
96
- a.timeout = timeout if timeout
97
- }.attempt(&block)
98
- end
99
- end
1
+ require 'timeout'
2
+
3
+ class Attempt
4
+ VERSION = '0.1.1'
5
+
6
+ # Number of attempts to make before failing. The default is 3.
7
+ attr_accessor :tries
8
+
9
+ # Number of seconds to wait between attempts. The default is 60.
10
+ attr_accessor :interval
11
+
12
+ # A boolean value that determines whether errors that would have been
13
+ # raised should be sent to STDERR as warnings. The default is true.
14
+ attr_accessor :warnings
15
+
16
+ # If you provide an IO handle to this option then errors that would
17
+ # have been raised are sent to that handle.
18
+ attr_accessor :log
19
+
20
+ # If set, this increments the interval with each failed attempt by that
21
+ # number of seconds.
22
+ attr_accessor :increment
23
+
24
+ # If set, the code block is further wrapped in a timeout block.
25
+ attr_accessor :timeout
26
+
27
+ # Determines which exception level to check when looking for errors to
28
+ # retry. The default is 'Exception' (i.e. all errors).
29
+ attr_accessor :level
30
+
31
+ # :call-seq:
32
+ # Attempt.new{ |a| ... }
33
+ #
34
+ # Creates and returns a new +Attempt+ object. Use a block to set the
35
+ # accessors.
36
+ #
37
+ def initialize
38
+ @tries = 3 # Reasonable default
39
+ @interval = 60 # Reasonable default
40
+ @log = nil # Should be an IO handle, if provided
41
+ @increment = nil # Should be an int, if provided
42
+ @timeout = nil # Wrap the code in a timeout block if provided
43
+ @level = Exception # Level of exception to be caught
44
+ @warnings = true # Errors sent to STDERR as warnings if true
45
+
46
+ yield self if block_given?
47
+ end
48
+
49
+ def attempt
50
+ count = 1
51
+ begin
52
+ if @timeout
53
+ Timeout.timeout(@timeout){ yield }
54
+ else
55
+ yield
56
+ end
57
+ rescue @level => error
58
+ @tries -= 1
59
+ if @tries > 0
60
+ msg = "Error on attempt # #{count}: #{error}; retrying"
61
+ count += 1
62
+ warn msg if @warnings
63
+ @log.puts msg if @log
64
+ @interval += @increment if @increment
65
+ sleep @interval
66
+ retry
67
+ end
68
+ raise
69
+ end
70
+ end
71
+ end
72
+
73
+ module Kernel
74
+ # :call-seq:
75
+ # attempt(tries = 3, interval = 60, timeout = nil){ # some op }
76
+ #
77
+ # Attempt to perform the operation in the provided block up to +tries+
78
+ # times, sleeping +interval+ between each try. By default the number
79
+ # of tries defaults to 3, the interval defaults to 60 seconds, and there
80
+ # is no timeout specified.
81
+ #
82
+ # If +timeout+ is provided then the operation is wrapped in a Timeout
83
+ # block as well. This is handy for those rare occasions when an IO
84
+ # connection could hang indefinitely, for example.
85
+ #
86
+ # If the operation still fails the (last) error is then re-raised.
87
+ #
88
+ # This is really just a wrapper for Attempt.new where the simple case is
89
+ # good enough i.e. you don't care about warnings, increments or logging,
90
+ # and you want a little added convenience.
91
+ #
92
+ # Example:
93
+ #
94
+ # # Make 3 attempts to connect to the database, 60 seconds apart.
95
+ # attempt{ DBI.connect(dsn, user, passwd) }
96
+ #
97
+ def attempt(tries = 3, interval = 60, timeout = nil, &block)
98
+ raise 'no block given' unless block_given?
99
+ Attempt.new{ |a|
100
+ a.tries = tries
101
+ a.interval = interval
102
+ a.timeout = timeout if timeout
103
+ }.attempt(&block)
104
+ end
105
+ end
@@ -1,42 +1,40 @@
1
- ###########################################################
2
- # tc_attempt.rb
3
- #
4
- # Test case for the attempt package.
5
- ###########################################################
6
- Dir.chdir('..') if File.basename(Dir.pwd) == 'test'
7
- $LOAD_PATH.unshift(Dir.pwd + '/lib')
8
-
9
- require 'attempt'
10
- require 'test/unit'
11
-
12
- print "\n== You will see a warning or two when running these tests ==\n\n"
13
-
14
- class TC_Attempt < Test::Unit::TestCase
15
- def setup
16
- @tries = 2
17
- @interval = 0.1
18
- @timeout = 0.1
19
- end
20
-
21
- def test_version
22
- assert_equal('0.1.0', Attempt::VERSION)
23
- end
24
-
25
- def test_attempt_basic
26
- assert_nothing_raised{ attempt{ 2 + 2 } }
27
- assert_nothing_raised{ attempt(@tries){ 2 + 2 } }
28
- assert_nothing_raised{ attempt(@tries, @interval){ 2 + 2 } }
29
- assert_nothing_raised{ attempt(@tries, @interval, @timeout){ 2 + 2 } }
30
- end
31
-
32
- def test_attempt_expected_errors
33
- assert_raises(Timeout::Error){ attempt(1, 1, @timeout){ sleep 5 } }
34
- assert_raises(RuntimeError){ attempt(2,2){ raise } }
35
- end
36
-
37
- def teardown
38
- @tries = nil
39
- @interval = nil
40
- @timeout = nil
41
- end
42
- end
1
+ #####################################################################
2
+ # tc_attempt.rb
3
+ #
4
+ # Test case for the attempt package. You should run this test case
5
+ # via the 'rake test' Rakefile task.
6
+ #####################################################################
7
+ require 'attempt'
8
+ require 'test/unit'
9
+
10
+ print "\n== You will see a warning or two when running these tests ==\n\n"
11
+
12
+ class TC_Attempt < Test::Unit::TestCase
13
+ def setup
14
+ @tries = 2
15
+ @interval = 0.1
16
+ @timeout = 0.1
17
+ end
18
+
19
+ def test_version
20
+ assert_equal('0.1.1', Attempt::VERSION)
21
+ end
22
+
23
+ def test_attempt_basic
24
+ assert_nothing_raised{ attempt{ 2 + 2 } }
25
+ assert_nothing_raised{ attempt(@tries){ 2 + 2 } }
26
+ assert_nothing_raised{ attempt(@tries, @interval){ 2 + 2 } }
27
+ assert_nothing_raised{ attempt(@tries, @interval, @timeout){ 2 + 2 } }
28
+ end
29
+
30
+ def test_attempt_expected_errors
31
+ assert_raises(Timeout::Error){ attempt(1, 1, @timeout){ sleep 5 } }
32
+ assert_raises(RuntimeError){ attempt(2,2){ raise } }
33
+ end
34
+
35
+ def teardown
36
+ @tries = nil
37
+ @interval = nil
38
+ @timeout = nil
39
+ end
40
+ end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: attempt
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
7
- date: 2006-06-09 00:00:00 -05:00
6
+ version: 0.1.1
7
+ date: 2007-07-31 00:00:00 -06:00
8
8
  summary: A thin wrapper for begin + rescue + sleep + retry
9
9
  require_paths:
10
10
  - lib
@@ -25,15 +25,15 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
25
  platform: ruby
26
26
  signing_key:
27
27
  cert_chain:
28
+ post_install_message:
28
29
  authors:
29
30
  - Daniel J. Berger
30
31
  files:
31
32
  - lib/attempt.rb
32
33
  - CHANGES
33
- - CVS
34
34
  - MANIFEST
35
35
  - README
36
- - test/CVS
36
+ - Rakefile
37
37
  - test/tc_attempt.rb
38
38
  test_files:
39
39
  - test/tc_attempt.rb
@@ -42,6 +42,7 @@ rdoc_options: []
42
42
  extra_rdoc_files:
43
43
  - README
44
44
  - CHANGES
45
+ - MANIFEST
45
46
  executables: []
46
47
 
47
48
  extensions: []