attempt 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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: []