pester 0.2.0 → 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
  SHA1:
3
- metadata.gz: 72934e84c8c0e2fd2f04a00cf0bf813514e22ee6
4
- data.tar.gz: 67bdc3fd419f71dd3e5f9e4a49b507eeb97fd083
3
+ metadata.gz: f1f5ea594c429a04f50888d1869f4e829db2995a
4
+ data.tar.gz: 18eb22f587bcc68d708872c085d6f16ab746fc9c
5
5
  SHA512:
6
- metadata.gz: 2912019dd882c9f0d7f180e8de1c116efcad81af40ddccacdf39c81fc74250cd817f743a402ddb1e3a178da886e50322011d41815021c3ab7551ffd2a5372ade
7
- data.tar.gz: 39fc544569277ab0b22972342a480196292155eab48bf4b6c583012608d851fbf69ed3b663099657d6f38dbadfdbc21fe71fadaa3650cdb2c166e83bb7e02fe5
6
+ metadata.gz: 6150fbb4bf53a271945524e42b1672951e018a18a1505c61407dbed0f322862e4181260502009695d87e9d21aac3587c42e5b2ad6766b1f9a8622bcea62c5f7e
7
+ data.tar.gz: 4cb89d7f6d88e2591efbca5f57b513e5bb5111f902f33225c4b827174ef60e8902738e9be6750058f8d7581b16fa0b05bcb82a7e1fa16bb56c24ba8214094d3a
@@ -1,14 +1,29 @@
1
1
  Metrics/AbcSize:
2
- Max: 20
2
+ Max: 27
3
+
4
+ Metrics/CyclomaticComplexity:
5
+ Max: 7
3
6
 
4
7
  Metrics/LineLength:
5
8
  Max: 140
6
9
 
10
+ Metrics/MethodLength:
11
+ Max: 23
12
+
13
+ Metrics/PerceivedComplexity:
14
+ Max: 9
15
+
7
16
  Style/Documentation:
8
- Enabled: false
17
+ Enabled: false
18
+
19
+ Style/ModuleFunction:
20
+ Enabled: false
9
21
 
10
22
  Style/RaiseArgs:
11
- Enabled: false
23
+ Enabled: false
24
+
25
+ Style/SpaceAroundOperators:
26
+ Enabled: false
12
27
 
13
28
  Style/SignalException:
14
29
  Enabled: false
data/README.md CHANGED
@@ -11,7 +11,7 @@ From the outset, the goal of Pester is to offer a simple interface. For example:
11
11
 
12
12
  irb(main):001:0> require 'pester'
13
13
  => true
14
- irb(main):002:0> Pester.retry { fail 'derp' }
14
+ irb(main):002:0> Pester.retry_constant { fail 'derp' }
15
15
  W, [2015-04-04T10:37:46.413158 #87600] WARN -- : Failure encountered: derp, backing off and trying again 3 more times. etc etc
16
16
 
17
17
  will retry the block--which always fails--until Pester has exhausted its amount of retries. With no options provided, this will sleep for a constant number of seconds between attempts.
@@ -24,7 +24,7 @@ Pester's basic retry behaviors are defined by three options:
24
24
 
25
25
  `delay_interval` is the unit, in seconds, that will be delayed between attempts. Normally, this is just the total number of seconds, but it can change with other `Behavior`s. `max_attempts` is the number of tries Pester will make, including the initial one. If this is set to 1, Pester will basically not retry; less than 1, it will not even bother executing the block:
26
26
 
27
- irb(main):001:0> Pester.retry(max_attempts: 0) { puts 'Trying...'; fail 'derp' }
27
+ irb(main):001:0> Pester.retry_constant(max_attempts: 0) { puts 'Trying...'; fail 'derp' }
28
28
  => nil
29
29
 
30
30
  `on_retry` defines the behavior between retries, which can either be a custom block of code, or one of the predefined `Behavior`s, specifically in `Pester::Behaviors::Sleep`. If passed an empty lambda/block, Pester will immediately retry. When writing a custom behavior, `on_retry` expects a block that can be called with two parameters, `attempt_num`, and `delay_interval`, the idea being that these will mostly be used to define a function that determines just how long to sleep between attempts.
@@ -35,7 +35,7 @@ Three behaviors are provided out-of-the box:
35
35
  * `Linear` simply multiplies `attempt_num` by `delay_interval` and sleeps for that many seconds
36
36
  * `Exponential` sleeps for 2<sup>(`attempt_num` - 1)</sup> * `delay_interval` seconds
37
37
 
38
- All three are available either by passing the behaviors to `on_retry`, or by calling the increasingly-verbosely-named `retry` (constant), `retry_with_backoff` (linear), or `retry_with_exponential_backoff` (exponential).
38
+ All three are available either by passing the behaviors to `on_retry`, or by calling the increasingly-verbosely-named `retry_constant` (constant), `retry_with_backoff` (linear), or `retry_with_exponential_backoff` (exponential). `retry` by itself *will not* actually retry anything, unless provided with an `on_retry` function, either per-call or in the relevant environment.
39
39
 
40
40
  Pester does log retry attempts (see below), however custom retry behavior that wraps existing `Behavior`s may be appropriate for logging custom information, incrementing statsd counters, etc. Also of note, different loggers can be passed per-call via the `logger` option.
41
41
 
@@ -51,7 +51,7 @@ Pester can be configured to be picky about what it chooses to retry and what it
51
51
 
52
52
  The first two are mutually-exclusive whitelist and blacklists, both taking either a single error class or an array. Raising an error not covered by `retry_error_classes` (whitelist) causes it to immediately fail:
53
53
 
54
- irb(main):002:0> Pester.retry(retry_error_classes: NotImplementedError) do
54
+ irb(main):002:0> Pester.retry_constant(retry_error_classes: NotImplementedError) do
55
55
  puts 'Trying...'
56
56
  fail 'derp'
57
57
  end
@@ -60,7 +60,7 @@ The first two are mutually-exclusive whitelist and blacklists, both taking eithe
60
60
 
61
61
  Raising an error covered by `reraise_error_classes` (blacklist) causes it to immediately fail:
62
62
 
63
- irb(main):002:0> Pester.retry(reraise_error_classes: NotImplementedError) do
63
+ irb(main):002:0> Pester.retry_constant(reraise_error_classes: NotImplementedError) do
64
64
  puts 'Trying...'
65
65
  raise NotImplementedError.new('derp')
66
66
  end
@@ -69,7 +69,7 @@ Raising an error covered by `reraise_error_classes` (blacklist) causes it to imm
69
69
 
70
70
  `retry_error_messages` also takes a single string or array, and calls `include?` on the error message. If it matches, the error's retried:
71
71
 
72
- irb(main):002:0> Pester.retry(retry_error_messages: 'please') do
72
+ irb(main):002:0> Pester.retry_constant(retry_error_messages: 'please') do
73
73
  puts 'Trying...'
74
74
  fail 'retry this, please'
75
75
  end
@@ -78,7 +78,7 @@ Raising an error covered by `reraise_error_classes` (blacklist) causes it to imm
78
78
 
79
79
  Because it calls `include?`, this also works for regexes:
80
80
 
81
- irb(main):002:0> Pester.retry(retry_error_messages: /\d/) do
81
+ irb(main):002:0> Pester.retry_constant(retry_error_messages: /\d/) do
82
82
  puts 'Trying...'
83
83
  fail 'retry this 2'
84
84
  end
@@ -92,8 +92,8 @@ Because it calls `include?`, this also works for regexes:
92
92
  The easiest way to coordinate sets of Pester options across an app is via environments--these are basically option hashes configured in Pester by name:
93
93
 
94
94
  Pester.configure do |c|
95
- c.environments[:aws] = { max_attempts: 3, delay_interval: 5 }
96
- c.environments[:internal] = { max_attempts: 2, delay_interval: 0 }
95
+ c.environments[:aws] = { max_attempts: 3, delay_interval: 5, on_retry: Pester::Behaviors::Sleep::Constant }
96
+ c.environments[:internal] = { max_attempts: 2, delay_interval: 0, on_retry: Pester::Behaviors::Sleep::Constant }
97
97
  end
98
98
 
99
99
  This will create two environments, `aws` and `internal`, which allow you to employ different backoff strategies, depending on the usage context. These are employed simply by calling `Pester.environment_name.retry` (where `retry` can also be another helper method):
@@ -112,7 +112,7 @@ This will create two environments, `aws` and `internal`, which allow you to empl
112
112
 
113
113
  Environments can also be merged with retry helper methods:
114
114
 
115
- Pester.aws.retry # acts different from
115
+ Pester.aws.retry_constant # acts different from
116
116
  Pester.aws.retry_with_exponential_backoff
117
117
 
118
118
  where the helper method's `Behavior` will take precedence.
@@ -127,7 +127,7 @@ Pester will write retry and exhaustion information into your logs, by default us
127
127
 
128
128
  And thus:
129
129
 
130
- irb(main):002:0> Pester.retry(delay_interval: 1) { puts 'Trying...'; fail 'derp' }
130
+ irb(main):002:0> Pester.retry_constant(delay_interval: 1) { puts 'Trying...'; fail 'derp' }
131
131
  Trying...
132
132
  Trying...
133
133
  Trying...
@@ -5,22 +5,27 @@ require 'pester/config'
5
5
  require 'pester/version'
6
6
 
7
7
  module Pester
8
- def self.configure(&block)
8
+ extend self
9
+ attr_accessor :environments
10
+
11
+ def configure(&block)
9
12
  Config.configure(&block)
10
- unless Config.environments.nil?
11
- self.environments = Hash[Config.environments.select { |_, e| e.is_a?(Hash) }.map { |k, e| [k.to_sym, Environment.new(e)] }]
12
- end
13
+
14
+ return if Config.environments.nil?
15
+
16
+ valid_environments = Config.environments.select { |_, e| e.is_a?(Hash) }
17
+ @environments = Hash[valid_environments.map { |k, e| [k.to_sym, Environment.new(e)] }]
13
18
  end
14
19
 
15
- def self.retry(options = {}, &block)
20
+ def retry_constant(options = {}, &block)
16
21
  retry_action(options.merge(on_retry: Behaviors::Sleep::Constant), &block)
17
22
  end
18
23
 
19
- def self.retry_with_backoff(options = {}, &block)
24
+ def retry_with_backoff(options = {}, &block)
20
25
  retry_action(options.merge(on_retry: Behaviors::Sleep::Linear), &block)
21
26
  end
22
27
 
23
- def self.retry_with_exponential_backoff(options = {}, &block)
28
+ def retry_with_exponential_backoff(options = {}, &block)
24
29
  retry_action({ delay_interval: 1 }.merge(options).merge(on_retry: Behaviors::Sleep::Exponential), &block)
25
30
  end
26
31
 
@@ -49,7 +54,7 @@ module Pester
49
54
  # FileUtils.rm_r(directory)
50
55
  # end
51
56
 
52
- def self.retry_action(opts = {}, &block)
57
+ def retry_action(opts = {}, &block)
53
58
  merge_defaults(opts)
54
59
  if opts[:retry_error_classes] && opts[:reraise_error_classes]
55
60
  fail 'You can only have one of retry_error_classes or reraise_error_classes'
@@ -79,25 +84,21 @@ module Pester
79
84
  nil
80
85
  end
81
86
 
82
- def respond_to?(method_sym)
87
+ def respond_to?(method_sym, options = {}, &block)
83
88
  super || Config.environments.key?(method_sym)
84
89
  end
85
90
 
86
- def method_missing(method_sym)
87
- if Config.environments.key?(method_sym)
88
- Config.environments[method_sym]
91
+ def method_missing(method_sym, options = {}, &block)
92
+ if @environments.key?(method_sym)
93
+ @environments[method_sym]
89
94
  else
90
95
  super
91
96
  end
92
97
  end
93
98
 
94
- class << self
95
- attr_accessor :environments
96
- end
97
-
98
99
  private
99
100
 
100
- def self.should_retry?(e, opts = {})
101
+ def should_retry?(e, opts = {})
101
102
  retry_error_classes = opts[:retry_error_classes]
102
103
  retry_error_messages = opts[:retry_error_messages]
103
104
  reraise_error_classes = opts[:reraise_error_classes]
@@ -117,7 +118,7 @@ module Pester
117
118
  end
118
119
  end
119
120
 
120
- def self.merge_defaults(opts)
121
+ def merge_defaults(opts)
121
122
  opts[:retry_error_classes] = opts[:retry_error_classes] ? Array(opts[:retry_error_classes]) : nil
122
123
  opts[:retry_error_messages] = opts[:retry_error_messages] ? Array(opts[:retry_error_messages]) : nil
123
124
  opts[:reraise_error_classes] = opts[:reraise_error_classes] ? Array(opts[:reraise_error_classes]) : nil
@@ -127,4 +128,6 @@ module Pester
127
128
  opts[:on_max_attempts_exceeded] ||= Behaviors::WarnAndReraise
128
129
  opts[:logger] ||= Config.logger
129
130
  end
131
+
132
+ alias_method :retry, :retry_action
130
133
  end
@@ -1,3 +1,3 @@
1
1
  module Pester
2
- VERSION = '0.2.0'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -10,9 +10,9 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['marc@lumoslabs.com']
11
11
  spec.summary = 'Common block-based retry for external calls.'
12
12
  spec.description = <<-EOD
13
- |We found ourselves constantly wrapping network-facing calls with all kinds of bespoke,
14
- | copied, and rewritten retry logic. This gem is an attempt to unify common behaviors,
15
- | like simple retry, retry with linear backoff, and retry with exponential backoff.
13
+ We found ourselves constantly wrapping network-facing calls with all kinds of bespoke,
14
+ copied, and rewritten retry logic. This gem is an attempt to unify common behaviors,
15
+ like simple retry, retry with linear backoff, and retry with exponential backoff.
16
16
  EOD
17
17
  spec.homepage = 'https://github.com/lumoslabs/pester'
18
18
  spec.license = 'MIT'
@@ -275,22 +275,25 @@ describe '#environments' do
275
275
  let(:environment_name) { :abc }
276
276
  let(:options) { { option: 1234 } }
277
277
 
278
- it 'adds it to the Pester environment list' do
278
+ before do
279
279
  Pester.configure do |config|
280
280
  config.environments[environment_name] = options
281
281
  end
282
+ end
282
283
 
284
+ it 'adds it to the Pester environment list' do
283
285
  expect(Pester.environments.count).to eq(1)
284
286
  end
285
287
 
286
288
  it 'contains an Environment with the appropriate options' do
287
- Pester.configure do |config|
288
- config.environments[environment_name] = options
289
- end
290
-
291
289
  expect(Pester.environments[environment_name].class).to eq(Pester::Environment)
292
290
  expect(Pester.environments[environment_name].options).to eq(options)
293
291
  end
292
+
293
+ it 'contains an Environment addressable directly from Pester with the appropriate options' do
294
+ expect(Pester.send(environment_name).class).to eq(Pester::Environment)
295
+ expect(Pester.send(environment_name).options).to eq(options)
296
+ end
294
297
  end
295
298
  end
296
299
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pester
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Bollinger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-25 00:00:00.000000000 Z
11
+ date: 2015-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,9 +53,9 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.2'
55
55
  description: |2
56
- |We found ourselves constantly wrapping network-facing calls with all kinds of bespoke,
57
- | copied, and rewritten retry logic. This gem is an attempt to unify common behaviors,
58
- | like simple retry, retry with linear backoff, and retry with exponential backoff.
56
+ We found ourselves constantly wrapping network-facing calls with all kinds of bespoke,
57
+ copied, and rewritten retry logic. This gem is an attempt to unify common behaviors,
58
+ like simple retry, retry with linear backoff, and retry with exponential backoff.
59
59
  email:
60
60
  - marc@lumoslabs.com
61
61
  executables: []