retryable 1.3.1 → 1.3.2
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.
- data/LICENSE.md +1 -1
- data/README.md +13 -0
- data/lib/config.rb +16 -0
- data/lib/retryable.rb +4 -0
- data/lib/version.rb +16 -0
- data/retryable.gemspec +3 -2
- data/spec/lib/config_spec.rb +23 -0
- data/spec/lib/retryable_spec.rb +26 -27
- data/spec/spec_helper.rb +8 -1
- metadata +28 -9
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -89,6 +89,19 @@ retryable do |retries, exception|
|
|
89
89
|
end
|
90
90
|
```
|
91
91
|
|
92
|
+
You can temporary disable retryable blocks
|
93
|
+
--------
|
94
|
+
|
95
|
+
```
|
96
|
+
Retryble.enabled?
|
97
|
+
=> true
|
98
|
+
|
99
|
+
Retryble.disable
|
100
|
+
|
101
|
+
Retryble.enabled?
|
102
|
+
=> false
|
103
|
+
```
|
104
|
+
|
92
105
|
Installation
|
93
106
|
-------
|
94
107
|
|
data/lib/config.rb
ADDED
data/lib/retryable.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'version'
|
2
|
+
require 'config'
|
1
3
|
|
2
4
|
module Kernel
|
3
5
|
def retryable(options = {}, &block)
|
@@ -14,6 +16,7 @@ module Kernel
|
|
14
16
|
begin
|
15
17
|
return yield retries, retry_exception
|
16
18
|
rescue *on_exception => exception
|
19
|
+
raise unless Retryable.enabled?
|
17
20
|
raise unless exception.message =~ opts[:matching]
|
18
21
|
raise if retries+1 >= opts[:tries]
|
19
22
|
|
@@ -39,3 +42,4 @@ module Kernel
|
|
39
42
|
raise ArgumentError.new("[Retryable] Invalid options: #{invalid_options.join(", ")}") unless invalid_options.empty?
|
40
43
|
end
|
41
44
|
end
|
45
|
+
|
data/lib/version.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Retryable
|
2
|
+
class Version
|
3
|
+
MAJOR = 1 unless defined? Twitter::Version::MAJOR
|
4
|
+
MINOR = 3 unless defined? Twitter::Version::MINOR
|
5
|
+
PATCH = 2 unless defined? Twitter::Version::PATCH
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# @return [String]
|
10
|
+
def to_s
|
11
|
+
[MAJOR, MINOR, PATCH].compact.join('.')
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/retryable.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/version', __FILE__)
|
2
3
|
|
3
4
|
Gem::Specification.new do |gem|
|
4
5
|
gem.add_development_dependency 'bundler'
|
@@ -14,7 +15,7 @@ Gem::Specification.new do |gem|
|
|
14
15
|
gem.name = 'retryable'
|
15
16
|
gem.require_paths = ["lib"]
|
16
17
|
gem.required_rubygems_version = '>= 1.3.6'
|
17
|
-
gem.summary =
|
18
|
+
gem.summary = gem.description
|
18
19
|
gem.test_files = Dir.glob("spec/**/*")
|
19
|
-
gem.version =
|
20
|
+
gem.version = Retryable::Version
|
20
21
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Retryable do
|
4
|
+
it 'is enabled by default' do
|
5
|
+
Retryable.should be_enabled
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'could be disabled' do
|
9
|
+
Retryable.disable
|
10
|
+
Retryable.should_not be_enabled
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when disabled' do
|
14
|
+
before do
|
15
|
+
Retryable.disable
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'could be re-enabled' do
|
19
|
+
Retryable.enable
|
20
|
+
Retryable.should be_enabled
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/lib/retryable_spec.rb
CHANGED
@@ -1,26 +1,35 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe 'retryable' do
|
4
|
-
|
3
|
+
describe 'Kernel.retryable' do
|
5
4
|
before(:each) do
|
5
|
+
Retryable.enable
|
6
6
|
@attempt = 0
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
9
|
+
it 'catch StandardError only by default' do
|
10
10
|
lambda do
|
11
11
|
count_retryable(:tries => 2) { |tries, ex| raise Exception if tries < 1 }
|
12
12
|
end.should raise_error Exception
|
13
13
|
@try_count.should == 1
|
14
14
|
end
|
15
|
-
|
16
|
-
it
|
15
|
+
|
16
|
+
it 'retries on default exception' do
|
17
17
|
Kernel.should_receive(:sleep).once.with(1)
|
18
18
|
|
19
19
|
count_retryable(:tries => 2) { |tries, ex| raise StandardError if tries < 1 }
|
20
20
|
@try_count.should == 2
|
21
21
|
end
|
22
22
|
|
23
|
-
it
|
23
|
+
it 'does not retry if disabled' do
|
24
|
+
Retryable.disable
|
25
|
+
|
26
|
+
lambda do
|
27
|
+
count_retryable(:tries => 2) { raise }
|
28
|
+
end.should raise_error RuntimeError
|
29
|
+
@try_count.should == 1
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'executes *ensure* clause' do
|
24
33
|
ensure_cb = Proc.new do |retries|
|
25
34
|
retries.should == 0
|
26
35
|
end
|
@@ -28,7 +37,7 @@ describe 'retryable' do
|
|
28
37
|
Kernel.retryable(:ensure => ensure_cb) { }
|
29
38
|
end
|
30
39
|
|
31
|
-
it
|
40
|
+
it 'passes retry count and exception on retry' do
|
32
41
|
Kernel.should_receive(:sleep).once.with(1)
|
33
42
|
|
34
43
|
count_retryable(:tries => 2) do |tries, ex|
|
@@ -37,14 +46,14 @@ describe 'retryable' do
|
|
37
46
|
end
|
38
47
|
@try_count.should == 2
|
39
48
|
end
|
40
|
-
|
41
|
-
it
|
49
|
+
|
50
|
+
it 'makes another try if exception is covered by :on' do
|
42
51
|
Kernel.stub!(:sleep)
|
43
52
|
count_retryable(:on => [StandardError, ArgumentError, RuntimeError] ) { |tries, ex| raise ArgumentError if tries < 1 }
|
44
53
|
@try_count.should == 2
|
45
54
|
end
|
46
55
|
|
47
|
-
it
|
56
|
+
it 'does not try on unexpected exception' do
|
48
57
|
Kernel.stub!(:sleep)
|
49
58
|
lambda do
|
50
59
|
count_retryable(:on => RuntimeError ) { |tries, ex| raise StandardError if tries < 1 }
|
@@ -52,40 +61,40 @@ describe 'retryable' do
|
|
52
61
|
@try_count.should == 1
|
53
62
|
end
|
54
63
|
|
55
|
-
it
|
64
|
+
it 'retries three times' do
|
56
65
|
Kernel.stub!(:sleep)
|
57
66
|
count_retryable(:tries => 3) { |tries, ex| raise StandardError if tries < 2 }
|
58
67
|
@try_count.should == 3
|
59
68
|
end
|
60
69
|
|
61
|
-
it
|
70
|
+
it 'retries on default exception' do
|
62
71
|
Kernel.should_receive(:sleep).once.with(1)
|
63
72
|
|
64
73
|
count_retryable(:tries => 2) { |tries, ex| raise StandardError if tries < 1 }
|
65
74
|
@try_count.should == 2
|
66
75
|
end
|
67
76
|
|
68
|
-
it
|
77
|
+
it 'executes exponential backoff scheme for :sleep option' do
|
69
78
|
[1, 4, 16, 64].each { |i| Kernel.should_receive(:sleep).once.ordered.with(i) }
|
70
79
|
lambda do
|
71
80
|
Kernel.retryable(:tries => 5, :sleep => lambda { |n| 4**n }) { raise RangeError }
|
72
81
|
end.should raise_error RangeError
|
73
82
|
end
|
74
83
|
|
75
|
-
it
|
84
|
+
it 'does not retry any exception if :on is empty list' do
|
76
85
|
lambda do
|
77
86
|
count_retryable(:on => []) { raise }
|
78
87
|
end.should raise_error RuntimeError
|
79
88
|
@try_count.should == 1
|
80
89
|
end
|
81
90
|
|
82
|
-
it
|
91
|
+
it 'catches an exception that matches the regex' do
|
83
92
|
Kernel.should_receive(:sleep).once.with(1)
|
84
93
|
count_retryable(:matching => /IO timeout/) { |c,e| raise "yo, IO timeout!" if c == 0 }
|
85
94
|
@try_count.should == 2
|
86
95
|
end
|
87
96
|
|
88
|
-
it
|
97
|
+
it 'does not catch an exception that does not match the regex' do
|
89
98
|
should_not_receive :sleep
|
90
99
|
lambda do
|
91
100
|
count_retryable(:matching => /TimeError/) { raise "yo, IO timeout!" }
|
@@ -93,19 +102,9 @@ describe 'retryable' do
|
|
93
102
|
@try_count.should == 1
|
94
103
|
end
|
95
104
|
|
96
|
-
it
|
105
|
+
it 'does not allow invalid options' do
|
97
106
|
lambda do
|
98
107
|
retryable(:bad_option => 2) { raise "this is bad" }
|
99
108
|
end.should raise_error ArgumentError, '[Retryable] Invalid options: bad_option'
|
100
109
|
end
|
101
|
-
|
102
|
-
private
|
103
|
-
|
104
|
-
def count_retryable *opts
|
105
|
-
@try_count = 0
|
106
|
-
return Kernel.retryable(*opts) do |*args|
|
107
|
-
@try_count += 1
|
108
|
-
yield *args
|
109
|
-
end
|
110
|
-
end
|
111
110
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require File.dirname(__FILE__) + '/../lib/retryable'
|
3
2
|
require 'rspec'
|
4
3
|
|
@@ -6,4 +5,12 @@ RSpec.configure do |config|
|
|
6
5
|
# Remove this line if you don't want RSpec's should and should_not
|
7
6
|
# methods or matchers
|
8
7
|
require 'rspec/expectations'
|
8
|
+
|
9
|
+
def count_retryable(*opts)
|
10
|
+
@try_count = 0
|
11
|
+
return Kernel.retryable(*opts) do |*args|
|
12
|
+
@try_count += 1
|
13
|
+
yield *args
|
14
|
+
end
|
15
|
+
end
|
9
16
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: retryable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,11 +11,11 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-12-25 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
18
|
-
requirement:
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ! '>='
|
@@ -23,10 +23,15 @@ dependencies:
|
|
23
23
|
version: '0'
|
24
24
|
type: :development
|
25
25
|
prerelease: false
|
26
|
-
version_requirements:
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ! '>='
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '0'
|
27
32
|
- !ruby/object:Gem::Dependency
|
28
33
|
name: rspec
|
29
|
-
requirement:
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
30
35
|
none: false
|
31
36
|
requirements:
|
32
37
|
- - ! '>='
|
@@ -34,10 +39,15 @@ dependencies:
|
|
34
39
|
version: '0'
|
35
40
|
type: :development
|
36
41
|
prerelease: false
|
37
|
-
version_requirements:
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
38
48
|
- !ruby/object:Gem::Dependency
|
39
49
|
name: yard
|
40
|
-
requirement:
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
41
51
|
none: false
|
42
52
|
requirements:
|
43
53
|
- - ! '>='
|
@@ -45,7 +55,12 @@ dependencies:
|
|
45
55
|
version: '0'
|
46
56
|
type: :development
|
47
57
|
prerelease: false
|
48
|
-
version_requirements:
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
49
64
|
description: Kernel#retryable, allow for retrying of code blocks.
|
50
65
|
email: loci.master@gmail.com
|
51
66
|
executables: []
|
@@ -57,7 +72,10 @@ files:
|
|
57
72
|
- README.md
|
58
73
|
- Rakefile
|
59
74
|
- retryable.gemspec
|
75
|
+
- lib/config.rb
|
60
76
|
- lib/retryable.rb
|
77
|
+
- lib/version.rb
|
78
|
+
- spec/lib/config_spec.rb
|
61
79
|
- spec/lib/retryable_spec.rb
|
62
80
|
- spec/lib/retryable_spec.rbc
|
63
81
|
- spec/spec_helper.rb
|
@@ -82,11 +100,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
100
|
version: 1.3.6
|
83
101
|
requirements: []
|
84
102
|
rubyforge_project:
|
85
|
-
rubygems_version: 1.8.
|
103
|
+
rubygems_version: 1.8.23
|
86
104
|
signing_key:
|
87
105
|
specification_version: 3
|
88
106
|
summary: Kernel#retryable, allow for retrying of code blocks.
|
89
107
|
test_files:
|
108
|
+
- spec/lib/config_spec.rb
|
90
109
|
- spec/lib/retryable_spec.rb
|
91
110
|
- spec/lib/retryable_spec.rbc
|
92
111
|
- spec/spec_helper.rb
|