retryable 1.3.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## Retryable 2.0.0 ##
2
+
3
+ * Retryable can now be used without monkey patching Kernel module(use `Retryable.retryable` instead). Thanks @oppegard
4
+
1
5
  ## Retryable 1.3.6 ##
2
6
 
3
7
  * Fixed warning: assigned but unused variable - tries. Thanks @amatsuda
data/README.md CHANGED
@@ -24,7 +24,7 @@ Open an URL, retry up to two times when an `OpenURI::HTTPError` occurs.
24
24
  ``` ruby
25
25
  require "open-uri"
26
26
 
27
- retryable(:tries => 3, :on => OpenURI::HTTPError) do
27
+ Retryable.retryable(:tries => 3, :on => OpenURI::HTTPError) do
28
28
  xml = open("http://example.com/test.xml").read
29
29
  end
30
30
  ```
@@ -33,7 +33,7 @@ Do _something_, retry up to four times for either `ArgumentError` or
33
33
  `TimeoutError` exceptions.
34
34
 
35
35
  ``` ruby
36
- retryable(:tries => 5, :on => [ArgumentError, TimeoutError]) do
36
+ Retryable.retryable(:tries => 5, :on => [ArgumentError, TimeoutError]) do
37
37
  # some crazy code
38
38
  end
39
39
  ```
@@ -49,7 +49,7 @@ ensure_cb = Proc.new do |retries|
49
49
  f.close
50
50
  end
51
51
 
52
- retryable(:ensure => ensure_cb) do
52
+ Retryable.retryable(:ensure => ensure_cb) do
53
53
  # process file
54
54
  end
55
55
  ```
@@ -63,9 +63,9 @@ Sleeping
63
63
  By default Retryable waits for one second between retries. You can change this and even provide your own exponential backoff scheme.
64
64
 
65
65
  ```
66
- retryable(:sleep => 0) { } # don't pause at all between retries
67
- retryable(:sleep => 10) { } # sleep ten seconds between retries
68
- retryable(:sleep => lambda { |n| 4**n }) { } # sleep 1, 4, 16, etc. each try
66
+ Retryable.retryable(:sleep => 0) { } # don't pause at all between retries
67
+ Retryable.retryable(:sleep => 10) { } # sleep ten seconds between retries
68
+ Retryable.retryable(:sleep => lambda { |n| 4**n }) { } # sleep 1, 4, 16, etc. each try
69
69
  ```
70
70
 
71
71
  Matching error messages
@@ -73,7 +73,7 @@ Matching error messages
73
73
  You can also retry based on the exception message:
74
74
 
75
75
  ```
76
- retryable(:matching => /IO timeout/) do |retries, exception|
76
+ Retryable.retryable(:matching => /IO timeout/) do |retries, exception|
77
77
  raise "yo, IO timeout!" if retries == 0
78
78
  end
79
79
  ```
@@ -83,7 +83,7 @@ Block Parameters
83
83
  Your block is called with two optional parameters: the number of tries until now, and the most recent exception.
84
84
 
85
85
  ```
86
- retryable do |retries, exception|
86
+ Retryable.retryable do |retries, exception|
87
87
  puts "try #{retries} failed with exception: #{exception}" if retries > 0
88
88
  pick_up_soap
89
89
  end
@@ -98,7 +98,7 @@ exception_cb = Proc.new do |exception|
98
98
  ExceptionNotifier.notify_exception(exception, :data => {:message => "it failed"})
99
99
  end
100
100
 
101
- retryable(:exception_cb => exception_cb) do
101
+ Retryable.retryable(:exception_cb => exception_cb) do
102
102
  # perform risky operation
103
103
  end
104
104
  ```
@@ -126,7 +126,7 @@ versions:
126
126
  * Ruby 1.9.2
127
127
  * Ruby 1.9.3
128
128
  * Ruby 2.0.0
129
- * Ruby 2.1.0
129
+ * Ruby 2.1.2
130
130
 
131
131
  If something doesn't work on one of these versions, it's a bug.
132
132
 
data/lib/retryable.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  require 'retryable/version'
2
2
  require 'retryable/config'
3
3
 
4
- module Kernel
5
- def retryable(options = {}, &block)
4
+ module Retryable
5
+ def self.retryable(options = {}, &block)
6
6
  opts = {:tries => 2, :sleep => 1, :on => StandardError, :matching => /.*/, :ensure => Proc.new {}, :exception_cb => Proc.new {}}
7
7
  check_for_invalid_options(options, opts)
8
8
  opts.merge!(options)
@@ -22,7 +22,7 @@ module Kernel
22
22
 
23
23
  # Interrupt Exception could be raised while sleeping
24
24
  begin
25
- sleep opts[:sleep].respond_to?(:call) ? opts[:sleep].call(retries) : opts[:sleep]
25
+ Kernel.sleep opts[:sleep].respond_to?(:call) ? opts[:sleep].call(retries) : opts[:sleep]
26
26
  rescue *on_exception
27
27
  end
28
28
 
@@ -37,7 +37,7 @@ module Kernel
37
37
 
38
38
  private
39
39
 
40
- def check_for_invalid_options(custom_options, default_options)
40
+ def self.check_for_invalid_options(custom_options, default_options)
41
41
  invalid_options = default_options.merge(custom_options).keys - default_options.keys
42
42
 
43
43
  raise ArgumentError.new("[Retryable] Invalid options: #{invalid_options.join(", ")}") unless invalid_options.empty?
@@ -1,8 +1,8 @@
1
1
  module Retryable
2
2
  class Version
3
- MAJOR = 1 unless defined? Retryable::Version::MAJOR
4
- MINOR = 3 unless defined? Retryable::Version::MINOR
5
- PATCH = 6 unless defined? Retryable::Version::PATCH
3
+ MAJOR = 2 unless defined? Retryable::Version::MAJOR
4
+ MINOR = 0 unless defined? Retryable::Version::MINOR
5
+ PATCH = 0 unless defined? Retryable::Version::PATCH
6
6
 
7
7
  class << self
8
8
 
@@ -1,13 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Retryable do
3
+ RSpec.describe Retryable do
4
4
  it 'is enabled by default' do
5
- Retryable.should be_enabled
5
+ expect(Retryable).to be_enabled
6
6
  end
7
7
 
8
8
  it 'could be disabled' do
9
9
  Retryable.disable
10
- Retryable.should_not be_enabled
10
+ expect(Retryable).not_to be_enabled
11
11
  end
12
12
 
13
13
  context 'when disabled' do
@@ -17,7 +17,7 @@ describe Retryable do
17
17
 
18
18
  it 'could be re-enabled' do
19
19
  Retryable.enable
20
- Retryable.should be_enabled
20
+ expect(Retryable).to be_enabled
21
21
  end
22
22
  end
23
23
  end
@@ -1,118 +1,118 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Kernel.retryable' do
3
+ RSpec.describe 'Retryable.retryable' do
4
4
  before(:each) do
5
5
  Retryable.enable
6
6
  @attempt = 0
7
7
  end
8
8
 
9
9
  it 'catch StandardError only by default' do
10
- lambda do
10
+ expect do
11
11
  count_retryable(:tries => 2) { |tries, ex| raise Exception if tries < 1 }
12
- end.should raise_error Exception
13
- @try_count.should == 1
12
+ end.to raise_error Exception
13
+ expect(@try_count).to eq(1)
14
14
  end
15
15
 
16
16
  it 'retries on default exception' do
17
- Kernel.should_receive(:sleep).once.with(1)
17
+ expect(Kernel).to receive(:sleep).once.with(1)
18
18
 
19
19
  count_retryable(:tries => 2) { |tries, ex| raise StandardError if tries < 1 }
20
- @try_count.should == 2
20
+ expect(@try_count).to eq(2)
21
21
  end
22
22
 
23
23
  it 'does not retry if disabled' do
24
24
  Retryable.disable
25
25
 
26
- lambda do
26
+ expect do
27
27
  count_retryable(:tries => 2) { raise }
28
- end.should raise_error RuntimeError
29
- @try_count.should == 1
28
+ end.to raise_error RuntimeError
29
+ expect(@try_count).to eq(1)
30
30
  end
31
31
 
32
32
  it 'executes *ensure* clause' do
33
33
  ensure_cb = Proc.new do |retries|
34
- retries.should == 0
34
+ expect(retries).to eq(0)
35
35
  end
36
36
 
37
- Kernel.retryable(:ensure => ensure_cb) { }
37
+ Retryable.retryable(:ensure => ensure_cb) { }
38
38
  end
39
39
 
40
40
  it 'passes retry count and exception on retry' do
41
- Kernel.should_receive(:sleep).once.with(1)
41
+ expect(Kernel).to receive(:sleep).once.with(1)
42
42
 
43
43
  count_retryable(:tries => 2) do |tries, ex|
44
- ex.class.should == StandardError if tries > 0
44
+ expect(ex.class).to eq(StandardError) if tries > 0
45
45
  raise StandardError if tries < 1
46
46
  end
47
- @try_count.should == 2
47
+ expect(@try_count).to eq(2)
48
48
  end
49
49
 
50
50
  it 'makes another try if exception is covered by :on' do
51
- Kernel.stub(:sleep)
51
+ allow(Kernel).to receive(:sleep)
52
52
  count_retryable(:on => [StandardError, ArgumentError, RuntimeError] ) { |tries, ex| raise ArgumentError if tries < 1 }
53
- @try_count.should == 2
53
+ expect(@try_count).to eq(2)
54
54
  end
55
55
 
56
56
  it 'does not try on unexpected exception' do
57
- Kernel.stub(:sleep)
58
- lambda do
57
+ allow(Kernel).to receive(:sleep)
58
+ expect do
59
59
  count_retryable(:on => RuntimeError ) { |tries, ex| raise StandardError if tries < 1 }
60
- end.should raise_error StandardError
61
- @try_count.should == 1
60
+ end.to raise_error StandardError
61
+ expect(@try_count).to eq(1)
62
62
  end
63
63
 
64
64
  it 'retries three times' do
65
- Kernel.stub(:sleep)
65
+ allow(Kernel).to receive(:sleep)
66
66
  count_retryable(:tries => 3) { |tries, ex| raise StandardError if tries < 2 }
67
- @try_count.should == 3
67
+ expect(@try_count).to eq(3)
68
68
  end
69
69
 
70
70
  it 'retries on default exception' do
71
- Kernel.should_receive(:sleep).once.with(1)
71
+ expect(Kernel).to receive(:sleep).once.with(1)
72
72
 
73
73
  count_retryable(:tries => 2) { |tries, ex| raise StandardError if tries < 1 }
74
- @try_count.should == 2
74
+ expect(@try_count).to eq(2)
75
75
  end
76
76
 
77
77
  it 'executes exponential backoff scheme for :sleep option' do
78
- [1, 4, 16, 64].each { |i| Kernel.should_receive(:sleep).once.ordered.with(i) }
79
- lambda do
80
- Kernel.retryable(:tries => 5, :sleep => lambda { |n| 4**n }) { raise RangeError }
81
- end.should raise_error RangeError
78
+ [1, 4, 16, 64].each { |i| expect(Kernel).to receive(:sleep).once.ordered.with(i) }
79
+ expect do
80
+ Retryable.retryable(:tries => 5, :sleep => lambda { |n| 4**n }) { raise RangeError }
81
+ end.to raise_error RangeError
82
82
  end
83
83
 
84
84
  it 'does not retry any exception if :on is empty list' do
85
- lambda do
85
+ expect do
86
86
  count_retryable(:on => []) { raise }
87
- end.should raise_error RuntimeError
88
- @try_count.should == 1
87
+ end.to raise_error RuntimeError
88
+ expect(@try_count).to eq(1)
89
89
  end
90
90
 
91
91
  it 'catches an exception that matches the regex' do
92
- Kernel.should_receive(:sleep).once.with(1)
92
+ expect(Kernel).to receive(:sleep).once.with(1)
93
93
  count_retryable(:matching => /IO timeout/) { |c,e| raise "yo, IO timeout!" if c == 0 }
94
- @try_count.should == 2
94
+ expect(@try_count).to eq(2)
95
95
  end
96
96
 
97
97
  it 'does not catch an exception that does not match the regex' do
98
- should_not_receive :sleep
99
- lambda do
98
+ expect(Kernel).not_to receive(:sleep)
99
+ expect do
100
100
  count_retryable(:matching => /TimeError/) { raise "yo, IO timeout!" }
101
- end.should raise_error RuntimeError
102
- @try_count.should == 1
101
+ end.to raise_error RuntimeError
102
+ expect(@try_count).to eq(1)
103
103
  end
104
104
 
105
105
  it 'does not allow invalid options' do
106
- lambda do
107
- retryable(:bad_option => 2) { raise "this is bad" }
108
- end.should raise_error ArgumentError, '[Retryable] Invalid options: bad_option'
106
+ expect do
107
+ Retryable.retryable(:bad_option => 2) { raise "this is bad" }
108
+ end.to raise_error ArgumentError, '[Retryable] Invalid options: bad_option'
109
109
  end
110
110
 
111
111
  it 'accepts a callback to run after an exception is rescued' do
112
- lambda do
113
- retryable(:sleep => 0, :exception_cb => Proc.new {|e| @raised = e.to_s }) {|tries, ex| raise StandardError.new("this is fun!") if tries < 1 }
114
- end.should_not raise_error
112
+ expect do
113
+ Retryable.retryable(:sleep => 0, :exception_cb => Proc.new {|e| @raised = e.to_s }) {|tries, ex| raise StandardError.new("this is fun!") if tries < 1 }
114
+ end.not_to raise_error
115
115
 
116
- @raised.should == "this is fun!"
116
+ expect(@raised).to eq("this is fun!")
117
117
  end
118
118
  end
data/spec/spec_helper.rb CHANGED
@@ -2,13 +2,11 @@ require File.dirname(__FILE__) + '/../lib/retryable'
2
2
  require 'rspec'
3
3
 
4
4
  RSpec.configure do |config|
5
- # Remove this line if you don't want RSpec's should and should_not
6
- # methods or matchers
7
- require 'rspec/expectations'
5
+ config.disable_monkey_patching!
8
6
 
9
7
  def count_retryable(*opts)
10
8
  @try_count = 0
11
- return Kernel.retryable(*opts) do |*args|
9
+ return Retryable.retryable(*opts) do |*args|
12
10
  @try_count += 1
13
11
  yield *args
14
12
  end
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: retryable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.6
4
+ version: 2.0.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Nikita Fedyashev
@@ -10,11 +11,12 @@ authors:
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
- date: 2014-09-05 00:00:00.000000000 Z
14
+ date: 2014-12-03 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: bundler
17
18
  requirement: !ruby/object:Gem::Requirement
19
+ none: false
18
20
  requirements:
19
21
  - - ~>
20
22
  - !ruby/object:Gem::Version
@@ -22,6 +24,7 @@ dependencies:
22
24
  type: :development
23
25
  prerelease: false
24
26
  version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
25
28
  requirements:
26
29
  - - ~>
27
30
  - !ruby/object:Gem::Version
@@ -36,40 +39,39 @@ files:
36
39
  - LICENSE.md
37
40
  - README.md
38
41
  - Rakefile
39
- - lib/retryable.rb
42
+ - retryable.gemspec
40
43
  - lib/retryable/config.rb
41
44
  - lib/retryable/version.rb
42
- - retryable.gemspec
45
+ - lib/retryable.rb
43
46
  - spec/lib/config_spec.rb
44
47
  - spec/lib/retryable_spec.rb
45
- - spec/lib/version_spec.rb
46
48
  - spec/spec_helper.rb
47
49
  homepage: http://github.com/nfedyashev/retryable
48
50
  licenses: []
49
- metadata: {}
50
51
  post_install_message:
51
52
  rdoc_options: []
52
53
  require_paths:
53
54
  - lib
54
55
  required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
55
57
  requirements:
56
- - - '>='
58
+ - - ! '>='
57
59
  - !ruby/object:Gem::Version
58
60
  version: '0'
59
61
  required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
60
63
  requirements:
61
- - - '>='
64
+ - - ! '>='
62
65
  - !ruby/object:Gem::Version
63
66
  version: 1.3.6
64
67
  requirements: []
65
68
  rubyforge_project:
66
- rubygems_version: 2.4.1
69
+ rubygems_version: 1.8.23
67
70
  signing_key:
68
- specification_version: 4
71
+ specification_version: 3
69
72
  summary: Kernel#retryable, allow for retrying of code blocks.
70
73
  test_files:
71
74
  - spec/lib/config_spec.rb
72
75
  - spec/lib/retryable_spec.rb
73
- - spec/lib/version_spec.rb
74
76
  - spec/spec_helper.rb
75
77
  has_rdoc:
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: c055a594c5bd9ebeb455b8185e027ea0d2ce259c
4
- data.tar.gz: 2cbbb09e5958d1f211810dbc762bfd962a102eaf
5
- SHA512:
6
- metadata.gz: c1f320b8298024f48f24677e4538d6da832287a7f00269da165b41454a242e2777bc7978c84916148afaa50bf63936090ae315da8e151b9fe3d6ae60d7085229
7
- data.tar.gz: f75b5c6bc559c0b5841a95d74914ac16fe24e399365aed35a3b9c7500c1c08d9a636def180e12f0773558252f1ddc371fcf5496f47e16301f300e00ebef904f2
@@ -1,7 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Retryable::Version do
4
- subject { Retryable::Version.to_s }
5
-
6
- it { should == '1.3.5' }
7
- end