take2 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad4dbf81975a5cc73474e2423a154804f890402129dc86bd3a84f33d3bb7014e
4
- data.tar.gz: 5db4c75eb7b03d975a6f4fcd36f92995107737e487cfa9e0ebc0b4c35683dbe9
3
+ metadata.gz: 1cb318b781932656dc817f9129c5621b55b99dc377968ffb0931f6ba3c044ab5
4
+ data.tar.gz: 28e00524af5f1ba059445018d47bffb0216b7517949d4ad8ed61da951db3be6f
5
5
  SHA512:
6
- metadata.gz: 318ddd7bc40de226b01e17d7f54106f34e41b63317ec14bd146c9df2a2cca003341c34c93929771bd13caf92d82759f9abb9d92e1d151df758877bf34eff5e01
7
- data.tar.gz: c50474f5331470bf1ac546507a6fd13c36f70f97fe0a7e98554c73c7cc94ab18861566d1998190fa517ea8ab7d3418244c16de1a014486522fdd7f4667f68890
6
+ metadata.gz: b9c3335fd97336deb6e7f1b0e82cf040779dbec24bb81b20b1b8bff5422e3c3612abdc49eb5c8b09e609d3e8a17941c64fdb5c4dfd417d7ebb7cec4a3a9d4ca4
7
+ data.tar.gz: 03aea65024971befd1c0e1db2e8d2a1dae3d9bf8ad82f87017d8c75b0461246cc5e366ef33e90dae1f4201b97b673e1acdbec8212ead4d64428104e3b6d72cf4
data/.gitignore CHANGED
@@ -48,3 +48,6 @@ build-iPhoneSimulator/
48
48
 
49
49
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
50
  .rvmrc
51
+ .idea
52
+ .ruby-gemset
53
+ .ruby-version
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- take2 (0.1.1)
4
+ take2 (1.0.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -22,7 +22,7 @@ GEM
22
22
  pry-nav (0.2.4)
23
23
  pry (>= 0.9.10, < 0.11.0)
24
24
  rainbow (3.0.0)
25
- rake (12.3.1)
25
+ rake (13.0.1)
26
26
  rspec (3.8.0)
27
27
  rspec-core (~> 3.8.0)
28
28
  rspec-expectations (~> 3.8.0)
@@ -60,4 +60,4 @@ DEPENDENCIES
60
60
  take2!
61
61
 
62
62
  BUNDLED WITH
63
- 1.16.6
63
+ 1.17.3
data/README.md CHANGED
@@ -3,9 +3,9 @@
3
3
  ![Gem](https://img.shields.io/gem/dt/take2.svg)
4
4
  ![GitHub last commit](https://img.shields.io/github/last-commit/restaurant-cheetah/take2.svg)
5
5
  ![Gem](https://img.shields.io/gem/v/take2.svg)
6
- Define rules for retrying behavior.
7
- Yield block of code into the public api of the take2.
8
- Things getting take two :)
6
+ 1. Define rules for retrying behavior.
7
+ 2. Yield block of code into the with_retry method.
8
+ 3. Things getting take two :)
9
9
 
10
10
  ## Install
11
11
 
@@ -15,64 +15,57 @@ gem install take2
15
15
  ## Examples
16
16
 
17
17
  ```ruby
18
- class KratosService
18
+ class Service
19
19
  include Take2
20
20
 
21
-
22
21
  number_of_retries 3
23
-
22
+
24
23
  # Could be configured globally or on class level.
25
- retriable_errors Net::HTTPRetriableError, Net::HTTPServerException
24
+ retriable_errors Net::HTTPRetriableError, Errno::ECONNRESET
26
25
 
27
26
  # Retry unless the response status is 5xx. The implementation is dependent of the http lib in use.
28
27
  retriable_condition proc { |error| error.response.code < 500 }
29
28
 
30
29
  # Defines callable code to run before next retry. Could be an out put to some logger.
31
- on_retry proc { |error, tries| puts "#{self.name} - Retrying.. #{tries} of #{self.retriable_configuration[:retries]} (#{error})" }
32
-
33
- # The available strategies are:
30
+ on_retry proc { |error, tries| puts "#{name} - Retrying.. #{tries} of #{retriable_configuration[:retries]} (#{error})" }
31
+
32
+ # The available strategies are:
34
33
  # type :constant, start: 2 => [2, 2, 2, 2 ... ]
35
34
  # type :linear, start: 3, factor: 2 => [3, 6, 12, 24 ... ]
36
35
  # type :fibonacci, start: 2 => [2, 3, 5, 8, 13 ... ]
37
- # type :exponential, start: 3 => [3, 7, 12, 28, 47 ... ]
36
+ # type :exponential, start: 3 => [3, 7, 12, 28, 47 ... ]
38
37
  backoff_strategy type: :fibonacci, start: 3
39
38
 
40
- def call_boy
41
- call_api_with_retry do
42
- # Some logic that might raise..
43
- # If it will raise retriable, magic happens.
44
- # If not the original error re raised
39
+ class << self
40
+ def call
41
+ with_retry do
42
+ # Some logic that might raise..
43
+ # If it will raise retriable, magic happens.
44
+ # If not the original error re raised
45
45
 
46
- raise Net::HTTPRetriableError.new 'Release the Kraken...many times!!', nil
46
+ raise Net::HTTPRetriableError.new('Release the Kraken...many times!!', nil)
47
+ end
47
48
  end
48
- end
49
49
 
50
- # Pass custom options per method call
51
- # The class defaults will not be overwritten
52
- def kill_baldur
53
- call_api_with_retry(retries: 2, retriable: [IOError], retry_proc: proc {}, retry_condition_proc: proc {}) do
54
- # Some logic that might raise..
50
+ # Pass custom options per method call
51
+ # The class defaults will not be overwritten
52
+ def read(file)
53
+ with_retry(retries: 2, retriable: [IOError], retry_proc: proc {}, retry_condition_proc: proc {}) do
54
+ # Some logic that might raise..
55
+ end
55
56
  end
56
57
  end
57
-
58
58
  end
59
59
 
60
- KratosService.new.call_boy
60
+ Service.call
61
61
  #=> KratosService - Retrying.. 3 of 3 (Release the Kraken...many times!!)
62
62
  #=> KratosService - Retrying.. 2 of 3 (Release the Kraken...many times!!)
63
63
  #=> KratosService - Retrying.. 1 of 3 (Release the Kraken...many times!!)
64
64
  # After the retrying is done, original error re-raised
65
65
  #=> Net::HTTPRetriableError: Release the Kraken...many times!!
66
66
 
67
- # Not wrapping with method
68
- KratosService.new.call_api_with_retry { 1 / 0 }
69
-
70
- # Or..
71
- Class.new { include Take2 }.new.call_api_with_retry { 1 / 0 }
72
-
73
-
74
67
  # Current configuration hash
75
- KratosService.retriable_configuration
68
+ Service.retriable_configuration
76
69
 
77
70
  ```
78
71
 
@@ -84,15 +77,13 @@ KratosService.retriable_configuration
84
77
 
85
78
  Take2.configure do |config|
86
79
  config.retries = 3
87
- config.retriable = [
88
- Net::HTTPServerException,
80
+ config.retriable = [
89
81
  Net::HTTPRetriableError,
90
82
  Errno::ECONNRESET,
91
83
  IOError
92
84
  ].freeze
93
- config.retry_condition_proc = proc {false}
94
- config.time_to_sleep = nil
95
- config.retry_proc = proc {Rails.logger.info "Retry message"}
85
+ config.retry_condition_proc = proc { false }
86
+ config.retry_proc = proc { Rails.logger.info "Retry message" }
96
87
  config.backoff_intervals = Take2::Backoff.new(:linear, 1).intervals
97
88
  end
98
89
  ```
@@ -23,11 +23,14 @@ module Take2
23
23
  end
24
24
 
25
25
  def local_defaults(options)
26
- configuration.validate_options(options)
26
+ configuration.validate!(options)
27
27
  end
28
28
 
29
29
  def configure
30
- yield(config) if block_given?
30
+ if block_given?
31
+ yield(config)
32
+ config.validate!(config.to_hash)
33
+ end
31
34
  end
32
35
  end
33
36
 
@@ -48,7 +51,7 @@ module Take2
48
51
  # backoff_strategy type: :exponential, start: 3
49
52
  #
50
53
  # def give_me_food
51
- # call_api_with_retry do
54
+ # with_retry do
52
55
  # # Some logic that might raise..
53
56
  # # If it will raise retriable, magic happens.
54
57
  # # If not the original error re raised
@@ -107,9 +110,9 @@ module Take2
107
110
  # retriable_errors Net::HTTPRetriableError, Errno::ECONNRESET
108
111
  # end
109
112
  # Arguments:
110
- # errors: List of retiable errors
113
+ # errors: List of retriable errors
111
114
  def retriable_errors(*errors)
112
- message = 'All retriable errors must be StandardError decendants'
115
+ message = 'All retriable errors must be StandardError descendants'
113
116
  raise ArgumentError, message unless errors.all? { |e| e <= StandardError }
114
117
  self.retriable = errors
115
118
  end
@@ -143,15 +146,6 @@ module Take2
143
146
  self.retry_proc = proc
144
147
  end
145
148
 
146
- def sleep_before_retry(seconds)
147
- unless (seconds.is_a?(Integer) || seconds.is_a?(Float)) && seconds.positive?
148
- raise ArgumentError, 'Must be positive numer'
149
- end
150
- puts "DEPRECATION MESSAGE - The sleep_before_retry method is softly deprecated in favor of backoff_stategy \r
151
- where the time to sleep is a starting point on the backoff intervals. Please implement it instead."
152
- self.time_to_sleep = seconds
153
- end
154
-
155
149
  # Sets the backoff strategy
156
150
  #
157
151
  # Example:
@@ -179,9 +173,8 @@ module Take2
179
173
  attr_accessor(*Take2::Configuration::CONFIG_ATTRS)
180
174
 
181
175
  def set_defaults
182
- config = Take2.configuration.to_hash
183
- Take2::Configuration::CONFIG_ATTRS.each do |attr|
184
- instance_variable_set("@#{attr}", config[attr])
176
+ Take2.config.to_hash.each do |k, v|
177
+ instance_variable_set("@#{k}", v)
185
178
  end
186
179
  end
187
180
 
@@ -191,11 +184,7 @@ module Take2
191
184
  end
192
185
 
193
186
  def rest(config, tries)
194
- seconds = if config[:time_to_sleep].to_f > 0
195
- config[:time_to_sleep].to_f
196
- else
197
- next_interval(config[:backoff_intervals], config[:retries], tries)
198
- end
187
+ seconds = next_interval(config[:backoff_intervals], config[:retries], tries)
199
188
  sleep(seconds)
200
189
  end
201
190
 
@@ -8,8 +8,6 @@ module Take2
8
8
  :retriable,
9
9
  :retry_proc,
10
10
  :retry_condition_proc,
11
- :time_to_sleep,
12
- :backoff_setup,
13
11
  :backoff_intervals].freeze
14
12
 
15
13
  attr_accessor(*CONFIG_ATTRS)
@@ -17,19 +15,12 @@ module Take2
17
15
  def initialize(options = {})
18
16
  # Defaults
19
17
  @retries = 3
20
- @retriable = [
21
- Net::HTTPServerException,
22
- Net::HTTPRetriableError,
23
- Errno::ECONNRESET,
24
- IOError,
25
- ].freeze
18
+ @retriable = []
26
19
  @retry_proc = proc {}
27
20
  @retry_condition_proc = proc { false }
28
- @time_to_sleep = 0 # TODO: Soft deprecate time to sleep
29
- @backoff_setup = { type: :constant, start: 3 }
30
- @backoff_intervals = Backoff.new(*@backoff_setup.values).intervals
31
- # Overwriting the defaults
32
- validate_options(options, &setter)
21
+ @backoff_intervals = Backoff.new(:constant, 3).intervals
22
+
23
+ merge_options!(options)
33
24
  end
34
25
 
35
26
  def to_hash
@@ -42,38 +33,28 @@ module Take2
42
33
  public_send(value)
43
34
  end
44
35
 
45
- def validate_options(options)
36
+ def merge_options!(options = {})
37
+ validate!(options).each do |key, value|
38
+ public_send("#{key}=", value)
39
+ end
40
+ self
41
+ end
42
+
43
+ def validate!(options)
46
44
  options.each do |k, v|
47
45
  raise ArgumentError, "#{k} is not a valid configuration" unless CONFIG_ATTRS.include?(k)
48
46
  case k
49
47
  when :retries
50
48
  raise ArgumentError, "#{k} must be positive integer" unless v.is_a?(Integer) && v.positive?
51
- when :time_to_sleep
52
- raise ArgumentError, "#{k} must be positive number" unless (v.is_a?(Integer) || v.is_a?(Float)) && v >= 0
53
49
  when :retriable
54
50
  raise ArgumentError, "#{k} must be array of retriable errors" unless v.is_a?(Array)
51
+ when :backoff_intervals
52
+ raise ArgumentError, "#{k} must be array of retriable errors" unless v.is_a?(Array)
53
+ raise ArgumentError, "#{k} size must be greater or equal to number of retries" unless v.size >= retries
55
54
  when :retry_proc, :retry_condition_proc
56
55
  raise ArgumentError, "#{k} must be Proc" unless v.is_a?(Proc)
57
- when :backoff_setup
58
- available_types = [:constant, :linear, :fibonacci, :exponential]
59
- raise ArgumentError, 'Incorrect backoff type' unless available_types.include?(v[:type])
60
56
  end
61
- yield(k, v) if block_given?
62
57
  end
63
58
  end
64
-
65
- def setter
66
- ->(key, value) {
67
- if key == :backoff_setup
68
- assign_backoff_intervals(value)
69
- else
70
- public_send("#{key}=", value)
71
- end
72
- }
73
- end
74
-
75
- def assign_backoff_intervals(backoff_setup)
76
- @backoff_intervals = Backoff.new(backoff_setup[:type], backoff_setup[:start]).intervals
77
- end
78
59
  end
79
60
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Take2
4
- VERSION = "0.1.1"
4
+ VERSION = "1.0.0"
5
5
  end
@@ -11,12 +11,7 @@ RSpec.describe(Take2::Configuration) do
11
11
  end
12
12
 
13
13
  it 'has correct default retriable errors array' do
14
- expect(default.retriable).to(eql([
15
- Net::HTTPServerException,
16
- Net::HTTPRetriableError,
17
- Errno::ECONNRESET,
18
- IOError,
19
- ].freeze))
14
+ expect(default.retriable).to(eql([]))
20
15
  end
21
16
 
22
17
  it 'has default proc for retry_proc' do
@@ -29,10 +24,6 @@ RSpec.describe(Take2::Configuration) do
29
24
  expect(default.retry_condition_proc.call).to(eql(p.call))
30
25
  end
31
26
 
32
- it 'has correct default value for time_to_sleep' do
33
- expect(default.time_to_sleep).to(eql(0))
34
- end
35
-
36
27
  it 'has correct default value for backoff_intervals' do
37
28
  expect(default.backoff_intervals).to eql Array.new(10, 3)
38
29
  end
@@ -46,14 +37,13 @@ RSpec.describe(Take2::Configuration) do
46
37
  retriable: [Net::HTTPRetriableError],
47
38
  retry_condition_proc: proc { true },
48
39
  retry_proc: proc { 2 * 2 },
49
- time_to_sleep: 0,
50
- backoff_setup: { type: :linear, start: 3 }
40
+ backoff_intervals: [1, 2, 3, 4, 5]
51
41
  }
52
42
  end
53
43
 
54
44
  let!(:new_configuration) { described_class.new(new_configs_hash).to_hash }
55
45
 
56
- [:retries, :retriable, :retry_proc, :retry_condition_proc, :time_to_sleep].each do |key|
46
+ [:retries, :retriable, :retry_proc, :retry_condition_proc, :backoff_intervals].each do |key|
57
47
  it "sets the #{key} key" do
58
48
  if new_configs_hash[key].respond_to?(:call)
59
49
  expect(new_configuration[key].call).to(eql(new_configs_hash[key].call))
@@ -62,14 +52,6 @@ RSpec.describe(Take2::Configuration) do
62
52
  end
63
53
  end
64
54
  end
65
-
66
- it 'sets the backoff_intervals correctly' do
67
- expect(new_configuration[:backoff_intervals])
68
- .to eql(Take2::Backoff.new(
69
- new_configs_hash[:backoff_setup][:type],
70
- new_configs_hash[:backoff_setup][:start]
71
- ).intervals)
72
- end
73
55
  end
74
56
 
75
57
  context 'with invalid hash' do
@@ -80,12 +62,6 @@ RSpec.describe(Take2::Configuration) do
80
62
  end
81
63
  end
82
64
 
83
- context 'when time_to_sleep set to invalid value' do
84
- it 'raises ArgumentError' do
85
- expect { described_class.new(time_to_sleep: -1) }.to(raise_error(ArgumentError))
86
- end
87
- end
88
-
89
65
  context 'when retriable set to invalid value' do
90
66
  it 'raises ArgumentError' do
91
67
  expect { described_class.new(retriable: StandardError) }.to(raise_error(ArgumentError))
@@ -104,9 +80,15 @@ RSpec.describe(Take2::Configuration) do
104
80
  end
105
81
  end
106
82
 
107
- context 'when backoff_setup has incorrect type' do
83
+ context 'when backoff_intervals has incorrect type' do
84
+ it 'raises ArgumentError' do
85
+ expect { described_class.new(backoff_intervals: 1) }.to(raise_error(ArgumentError))
86
+ end
87
+ end
88
+
89
+ context 'when backoff_intervals size smaller then number of retries' do
108
90
  it 'raises ArgumentError' do
109
- expect { described_class.new(backoff_setup: { type: :log }) }.to(raise_error(ArgumentError))
91
+ expect { described_class.new(backoff_intervals: [1]) }.to(raise_error(ArgumentError))
110
92
  end
111
93
  end
112
94
  end
@@ -6,10 +6,9 @@ RSpec.describe(Take2) do
6
6
  let!(:config) do
7
7
  Take2.configure do |c|
8
8
  c.retries = 1
9
- c.retriable = [Net::HTTPServerException, Net::HTTPRetriableError].freeze
9
+ c.retriable = [Errno::ECONNRESET, Net::HTTPRetriableError].freeze
10
10
  c.retry_condition_proc = proc { false }
11
11
  c.retry_proc = proc {}
12
- c.time_to_sleep = 0
13
12
  c.backoff_intervals = Take2::Backoff.new(:linear, 1).intervals
14
13
  end
15
14
  end
@@ -35,10 +34,6 @@ RSpec.describe(Take2) do
35
34
  expect(subject[:retry_proc].call).to(eql(described_class.configuration[:retry_proc].call))
36
35
  end
37
36
 
38
- it 'has a default value for :time_to_sleep' do
39
- expect(subject[:time_to_sleep]).to(eql(described_class.configuration[:time_to_sleep]))
40
- end
41
-
42
37
  it 'has a default value for :backoff_intervals' do
43
38
  expect(subject[:backoff_intervals]).to eql((1..10).to_a)
44
39
  end
@@ -111,21 +106,6 @@ RSpec.describe(Take2) do
111
106
  end
112
107
  end
113
108
 
114
- describe '.sleep_before_retry' do
115
- context 'with valid argument' do
116
- it 'sets the :sleep_before_retry attribute' do
117
- klass.sleep_before_retry(3.5)
118
- expect(subject[:time_to_sleep]).to(eql(3.5))
119
- end
120
- end
121
-
122
- context 'with invalid argument' do
123
- it 'raises ArgumentError' do
124
- expect { klass.sleep_before_retry(-1) }.to(raise_error(ArgumentError))
125
- end
126
- end
127
- end
128
-
129
109
  describe '.backoff_setup' do
130
110
  context 'with valid arguments' do
131
111
  it 'sets the backoff_intervals' do
@@ -154,12 +134,14 @@ RSpec.describe(Take2) do
154
134
  describe 'class method' do
155
135
  let(:retriable_error) { Net::HTTPRetriableError.new('Release the Kraken...many times!!', nil) }
156
136
  before(:each) { @tries = 0 }
137
+
157
138
  it 'responds to the method' do
158
139
  expect(klass).to respond_to(:call_api_with_retry)
159
140
  expect(klass).to respond_to(:with_retry)
160
141
  expect(klass.method(:with_retry).original_name).to eq(klass.method(:call_api_with_retry).original_name)
161
142
  expect(klass.method(:with_retry).source_location).to eq(klass.method(:call_api_with_retry).source_location)
162
143
  end
144
+
163
145
  it 'retries correct number of times' do
164
146
  expect do
165
147
  klass.call_api_with_retry { wrath_the_gods_with retriable_error }
@@ -168,6 +150,7 @@ RSpec.describe(Take2) do
168
150
  nil
169
151
  end
170
152
  end
153
+
171
154
  describe 'instance method' do
172
155
  it 'responds to the method' do
173
156
  expect(object).to respond_to(:call_api_with_retry)
@@ -175,6 +158,7 @@ RSpec.describe(Take2) do
175
158
  expect(object.method(:with_retry).original_name).to eq(object.method(:call_api_with_retry).original_name)
176
159
  expect(object.method(:with_retry).source_location).to eq(object.method(:call_api_with_retry).source_location)
177
160
  end
161
+
178
162
  context 'when raised with non retriable error' do
179
163
  let(:error) { StandardError.new('Release the Kraken!!') }
180
164
 
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.email = ["evnomadx@gmail.com"]
12
12
  s.homepage = "https://github.com/restaurant-cheetah/take2"
13
13
  s.summary = "Provides Take2 for your APIs calls"
14
- s.description = "Retry API calls, methods or blocks of code. Define take2 retry behavior or use defaults and you good to go."
14
+ s.description = "Retry failed API calls, methods or blocks of code. Define take2 retry behavior on a class or method level and you good to go."
15
15
  s.post_install_message = "Getting Take2 is dead easy!"
16
16
 
17
17
  all_files = %x(git ls-files).split("\n")
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: take2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Magids
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-21 00:00:00.000000000 Z
11
+ date: 2020-08-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Retry API calls, methods or blocks of code. Define take2 retry behavior
14
- or use defaults and you good to go.
13
+ description: Retry failed API calls, methods or blocks of code. Define take2 retry
14
+ behavior on a class or method level and you good to go.
15
15
  email:
16
16
  - evnomadx@gmail.com
17
17
  executables: []
@@ -57,8 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
57
  - !ruby/object:Gem::Version
58
58
  version: '0'
59
59
  requirements: []
60
- rubyforge_project:
61
- rubygems_version: 2.7.9
60
+ rubygems_version: 3.0.8
62
61
  signing_key:
63
62
  specification_version: 4
64
63
  summary: Provides Take2 for your APIs calls