ridley 2.5.1 → 3.0.0.rc1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7015d6698dd19c93412740e2ff16f5432025e0ef
4
- data.tar.gz: 98f72e264ea4832ab085c887e71a001dad03ca35
3
+ metadata.gz: 507254a6cdf340a5c7e11ac8354043df5f66d5cf
4
+ data.tar.gz: bdea7bdd458295e87a7401968cba749a7aa8e738
5
5
  SHA512:
6
- metadata.gz: 6513631b259a1909e6624c101b0cf2f64757992b754f8dfb51514e606aefacb6b28ba8720491f457daaccfc81a8f2288cb72e3249fc3470247bfda2412176b2e
7
- data.tar.gz: e7a519e2bd14c9ed26be2bf9981e5d44003268589f8e3976ee4552af5d412f34a7d22d5a33e24871919720214fa64c9c71d54714db3ec3096215ee69d09a7e33
6
+ metadata.gz: a8f65480cb316c3b5ab316fa68687582a15014042003ed0d85a684af38aea0f10a83a39fb2fcb0514adfcaa7a41e18b9aff317a1fdf6390970ffea118389afd0
7
+ data.tar.gz: a9c3c56283f0873eaacee0fd5fbf6a9b9f09100886b704da43d83b96d9ebc6254665021c6516304adf02c5506dc5672247a25e0bfa1384e1130946340272daf6
@@ -18,8 +18,6 @@ module Ridley::Chef
18
18
 
19
19
  if ignore
20
20
  log.debug "Using '#{FILENAME}' at '#{ignore}'"
21
- else
22
- log.debug "Could not find '#{FILENAME}' at '#{path}'"
23
21
  end
24
22
 
25
23
  super(ignore, base: path)
@@ -239,8 +239,6 @@ module Ridley::Chef
239
239
  version = version_args.first
240
240
  @platforms[platform] = Solve::Constraint.new(version).to_s
241
241
  @platforms[platform]
242
- rescue Solve::Errors::InvalidConstraintFormat => ex
243
- raise InvalidVersionConstraint, ex.to_s
244
242
  end
245
243
 
246
244
  # Adds a dependency on another cookbook, with version checking strings.
@@ -257,8 +255,6 @@ module Ridley::Chef
257
255
  version = version_args.first
258
256
  @dependencies[cookbook] = Solve::Constraint.new(version).to_s
259
257
  @dependencies[cookbook]
260
- rescue Solve::Errors::InvalidConstraintFormat => ex
261
- raise InvalidVersionConstraint, ex.to_s
262
258
  end
263
259
 
264
260
  # Adds a recommendation for another cookbook, with version checking strings.
@@ -275,8 +271,6 @@ module Ridley::Chef
275
271
  version = version_args.first
276
272
  @recommendations[cookbook] = Solve::Constraint.new(version).to_s
277
273
  @recommendations[cookbook]
278
- rescue Solve::Errors::InvalidConstraintFormat => ex
279
- raise InvalidVersionConstraint, ex.to_s
280
274
  end
281
275
 
282
276
  # Adds a suggestion for another cookbook, with version checking strings.
@@ -293,8 +287,6 @@ module Ridley::Chef
293
287
  version = version_args.first
294
288
  @suggestions[cookbook] = Solve::Constraint.new(version).to_s
295
289
  @suggestions[cookbook]
296
- rescue Solve::Errors::InvalidConstraintFormat => ex
297
- raise InvalidVersionConstraint, ex.to_s
298
290
  end
299
291
 
300
292
  # Adds a conflict for another cookbook, with version checking strings.
@@ -311,8 +303,6 @@ module Ridley::Chef
311
303
  version = version_args.first
312
304
  @conflicting[cookbook] = Solve::Constraint.new(version).to_s
313
305
  @conflicting[cookbook]
314
- rescue Solve::Errors::InvalidConstraintFormat => ex
315
- raise InvalidVersionConstraint, ex.to_s
316
306
  end
317
307
 
318
308
  # Adds a recipe, definition, or resource provided by this cookbook.
@@ -333,8 +323,6 @@ module Ridley::Chef
333
323
  version = version_args.first
334
324
  @providing[cookbook] = Solve::Constraint.new(version).to_s
335
325
  @providing[cookbook]
336
- rescue Solve::Errors::InvalidConstraintFormat => ex
337
- raise InvalidVersionConstraint, ex.to_s
338
326
  end
339
327
 
340
328
  # Adds a cookbook that is replaced by this one, with version checking strings.
@@ -350,8 +338,6 @@ module Ridley::Chef
350
338
  version = version_args.first
351
339
  @replacing[cookbook] = Solve::Constraint.new(version).to_s
352
340
  @replacing[cookbook]
353
- rescue Solve::Errors::InvalidConstraintFormat => ex
354
- raise InvalidVersionConstraint, ex.to_s
355
341
  end
356
342
 
357
343
  # Adds a description for a recipe.
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module Ridley::Chef
2
4
  class Cookbook
3
5
  require_relative 'cookbook/metadata'
@@ -24,24 +26,24 @@ module Ridley::Chef
24
26
  # @param [#to_s] path
25
27
  # a path on disk to the location of a Cookbook
26
28
  #
27
- # @option options [String] :name
28
- # explicitly supply the name of the cookbook we are loading. This is useful if
29
- # you are dealing with a cookbook that does not have well-formed metadata
30
- #
31
29
  # @raise [IOError] if the path does not contain a metadata.rb or metadata.json file
32
30
  #
33
31
  # @return [Ridley::Chef::Cookbook]
34
- def from_path(path, options = {})
35
- path = Pathname.new(path)
36
- metadata = if (metadata_file = path.join(Metadata::COMPILED_FILE_NAME)).exist?
37
- Cookbook::Metadata.from_json(File.read(metadata_file))
38
- elsif (metadata_file = path.join(Metadata::RAW_FILE_NAME)).exist?
39
- Cookbook::Metadata.from_file(metadata_file)
32
+ def from_path(path)
33
+ path = Pathname.new(path)
34
+
35
+ if (file = path.join(Metadata::COMPILED_FILE_NAME)).exist?
36
+ metadata = Metadata.from_json(File.read(file))
37
+ elsif (file = path.join(Metadata::RAW_FILE_NAME)).exist?
38
+ metadata = Metadata.from_file(file)
40
39
  else
41
40
  raise IOError, "no #{Metadata::COMPILED_FILE_NAME} or #{Metadata::RAW_FILE_NAME} found at #{path}"
42
41
  end
43
42
 
44
- metadata.name(options[:name].presence || metadata.name.presence || File.basename(path))
43
+ unless metadata.name.presence
44
+ raise Ridley::Errors::MissingNameAttribute.new(path)
45
+ end
46
+
45
47
  new(metadata.name, path, metadata)
46
48
  end
47
49
  end
data/lib/ridley/client.rb CHANGED
@@ -140,7 +140,7 @@ module Ridley
140
140
  @options[:client_key] = File.expand_path(@options[:client_key])
141
141
  raise Errors::ClientKeyFileNotFoundOrInvalid, "client key is invalid or not found at: '#{@options[:client_key]}'" unless File.exist?(@options[:client_key]) && verify_client_key(::IO.read(@options[:client_key]))
142
142
  end
143
-
143
+
144
144
  @connection_registry = Celluloid::Registry.new
145
145
  @resources_registry = Celluloid::Registry.new
146
146
  @connection_supervisor = ConnectionSupervisor.new(@connection_registry, @options)
@@ -276,8 +276,8 @@ module Ridley
276
276
  end
277
277
 
278
278
  def finalize_callback
279
- @connection_supervisor.terminate if @connection_supervisor && @connection_supervisor.alive?
280
- @resources_supervisor.terminate if @resources_supervisor && @resources_supervisor.alive?
279
+ @connection_supervisor.async.terminate if @connection_supervisor
280
+ @resources_supervisor.async.terminate if @resources_supervisor
281
281
  end
282
282
  end
283
283
  end
@@ -44,10 +44,10 @@ module Ridley
44
44
  options = options.reverse_merge(retries: 5, retry_interval: 0.5)
45
45
  @client_name = client_name
46
46
  @client_key = client_key
47
- @retries = options[:retries]
48
- @retry_interval = options[:retry_interval]
47
+ @retries = options.delete(:retries)
48
+ @retry_interval = options.delete(:retry_interval)
49
49
 
50
- options[:builder] = Faraday::Builder.new do |b|
50
+ options[:builder] = Faraday::RackBuilder.new do |b|
51
51
  b.request :retry,
52
52
  max: @retries,
53
53
  interval: @retry_interval,
data/lib/ridley/errors.rb CHANGED
@@ -42,6 +42,29 @@ module Ridley
42
42
  "no encrypted data bag secret was set for this Ridley connection"
43
43
  end
44
44
  end
45
+ class FromFileParserError < RidleyError
46
+ def initialize(filename, error)
47
+ super "Could not parse `#{filename}': #{error.message}"
48
+
49
+ # Populate the backtrace with the actual error though
50
+ set_backtrace(error.backtrace)
51
+ end
52
+ end
53
+
54
+ class MissingNameAttribute < RidleyError
55
+ def initialize(path)
56
+ @path = path
57
+ end
58
+
59
+ def to_s
60
+ out = "The metadata at '#{@path}' does not contain a 'name' "
61
+ out << "attribute. While Chef does not strictly enforce this "
62
+ out << "requirement, Ridley cannot continue without a valid metadata "
63
+ out << "'name' entry."
64
+ out
65
+ end
66
+ alias_method :message, :to_s
67
+ end
45
68
 
46
69
  class BootstrapError < RidleyError; end
47
70
  class ClientKeyFileNotFoundOrInvalid < BootstrapError; end
@@ -3,7 +3,6 @@ require 'logger'
3
3
  module Ridley
4
4
  module Logging
5
5
  class << self
6
-
7
6
  # @return [Logger]
8
7
  def logger
9
8
  @logger ||= begin
@@ -87,4 +87,4 @@ module Ridley
87
87
  end
88
88
  end
89
89
 
90
- Faraday.register_middleware(:request, chef_auth: Ridley::Middleware::ChefAuth)
90
+ Faraday::Request.register_middleware chef_auth: Ridley::Middleware::ChefAuth
@@ -28,4 +28,4 @@ module Ridley
28
28
  end
29
29
  end
30
30
 
31
- Faraday.register_middleware(:response, chef_response: Ridley::Middleware::ChefResponse)
31
+ Faraday::Response.register_middleware chef_response: Ridley::Middleware::ChefResponse
@@ -132,4 +132,4 @@ module Ridley
132
132
  end
133
133
  end
134
134
 
135
- Faraday.register_middleware(:response, follow_redirects: Ridley::Middleware::FollowRedirects)
135
+ Faraday::Response.register_middleware follow_redirects: Ridley::Middleware::FollowRedirects
@@ -15,4 +15,4 @@ module Ridley
15
15
  end
16
16
  end
17
17
 
18
- Faraday.register_middleware(:response, gzip: Ridley::Middleware::Gzip)
18
+ Faraday::Response.register_middleware gzip: Ridley::Middleware::Gzip
@@ -106,4 +106,4 @@ module Ridley
106
106
  end
107
107
  end
108
108
 
109
- Faraday.register_middleware(:response, parse_json: Ridley::Middleware::ParseJson)
109
+ Faraday::Response.register_middleware parse_json: Ridley::Middleware::ParseJson
@@ -25,11 +25,11 @@ module Ridley::Mixin
25
25
  def from_file(filename)
26
26
  filename = filename.to_s
27
27
 
28
- if File.exists?(filename) && File.readable?(filename)
28
+ ensure_presence!(filename)
29
+
30
+ with_error_handling(filename) do
29
31
  self.instance_eval(IO.read(filename), filename, 1)
30
32
  self
31
- else
32
- raise IOError, "Could not open or read: '#{filename}'"
33
33
  end
34
34
  end
35
35
 
@@ -42,12 +42,38 @@ module Ridley::Mixin
42
42
  def class_from_file(filename)
43
43
  filename = filename.to_s
44
44
 
45
- if File.exists?(filename) && File.readable?(filename)
45
+ ensure_presence!(filename)
46
+
47
+ with_error_handling(filename) do
46
48
  self.class_eval(IO.read(filename), filename, 1)
47
49
  self
48
- else
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ # Ensure the given filename and path is readable
56
+ #
57
+ # @param [String] filename
58
+ #
59
+ # @raise [IOError]
60
+ # if the target file does not exist or is not readable
61
+ def ensure_presence!(filename)
62
+ unless File.exists?(filename) && File.readable?(filename)
49
63
  raise IOError, "Could not open or read: '#{filename}'"
50
64
  end
51
65
  end
66
+
67
+ # Execute the given block, handling any exceptions that occur
68
+ #
69
+ # @param [String] filename
70
+ #
71
+ # @raise [Ridley::Errors::FromFileParserError]
72
+ # if any exceptions if raised
73
+ def with_error_handling(filename)
74
+ yield
75
+ rescue => e
76
+ raise Ridley::Errors::FromFileParserError.new(filename, e)
77
+ end
52
78
  end
53
79
  end
@@ -171,10 +171,6 @@ module Ridley
171
171
  # @param [String] path
172
172
  # path to a cookbook on local disk
173
173
  #
174
- # @option options [String] :name
175
- # automatically populated by the metadata of the cookbook at the given path, but
176
- # in the event that the metadata does not contain a name it can be specified with
177
- # this option
178
174
  # @option options [Boolean] :force (false)
179
175
  # Upload the Cookbook even if the version already exists and is frozen on
180
176
  # the target Chef Server
@@ -187,7 +183,7 @@ module Ridley
187
183
  # @return [Hash]
188
184
  def upload(path, options = {})
189
185
  options = options.reverse_merge(validate: true, force: false, freeze: false)
190
- cookbook = Ridley::Chef::Cookbook.from_path(path, options.slice(:name))
186
+ cookbook = Ridley::Chef::Cookbook.from_path(path)
191
187
 
192
188
  unless (existing = find(cookbook.cookbook_name, cookbook.version)).nil?
193
189
  if existing.frozen? && options[:force] == false
@@ -31,7 +31,7 @@ module Ridley
31
31
  private
32
32
 
33
33
  def finalize_callback
34
- item_resource.terminate if item_resource && item_resource.alive?
34
+ item_resource.async.terminate if item_resource
35
35
  end
36
36
  end
37
37
  end
@@ -8,7 +8,7 @@ module Ridley
8
8
  def initialize(connection_registry, client_name, client_key, options = {})
9
9
  super(connection_registry)
10
10
  options = options.reverse_merge(pool_size: 4)
11
- @uploader = SandboxUploader.pool(size: options[:pool_size], args: [ client_name, client_key, options ])
11
+ @uploader = SandboxUploader.pool(size: options.delete(:pool_size), args: [ client_name, client_key, options ])
12
12
  end
13
13
 
14
14
  # Create a new Sandbox on the client's Chef Server. A Sandbox requires an
@@ -98,7 +98,7 @@ module Ridley
98
98
  attr_reader :uploader
99
99
 
100
100
  def finalize_callback
101
- uploader.terminate if uploader && uploader.alive?
101
+ uploader.async.terminate if uploader
102
102
  end
103
103
  end
104
104
  end
@@ -1,3 +1,3 @@
1
1
  module Ridley
2
- VERSION = "2.5.1"
2
+ VERSION = "3.0.0.rc1"
3
3
  end
data/ridley.gemspec CHANGED
@@ -23,10 +23,10 @@ Gem::Specification.new do |s|
23
23
  s.add_dependency 'buff-extensions', '~> 0.3'
24
24
  s.add_dependency 'buff-ignore', '~> 1.1'
25
25
  s.add_dependency 'buff-shell_out', '~> 0.1'
26
- s.add_dependency 'celluloid', '~> 0.15'
27
- s.add_dependency 'celluloid-io', '~> 0.15'
26
+ s.add_dependency 'celluloid', '~> 0.16.0.pre'
27
+ s.add_dependency 'celluloid-io', '~> 0.16.0.pre'
28
28
  s.add_dependency 'erubis'
29
- s.add_dependency 'faraday', '~> 0.8.4'
29
+ s.add_dependency 'faraday', '~> 0.9.0'
30
30
  s.add_dependency 'hashie', '>= 2.0.2'
31
31
  s.add_dependency 'json', '>= 1.7.7'
32
32
  s.add_dependency 'mixlib-authentication', '>= 1.3.0'
@@ -1,5 +1,5 @@
1
1
  RSpec.configuration.before(:each) do
2
- class Celluloid::ActorProxy
2
+ class Celluloid::CellProxy
3
3
  unless @rspec_compatible
4
4
  @rspec_compatible = true
5
5
  undef_method :should_receive if method_defined?(:should_receive)
@@ -15,10 +15,6 @@ describe Ridley::Chef::Cookbook do
15
15
  subject.from_path(cookbook_path).cookbook_name.should eql("example_cookbook")
16
16
  end
17
17
 
18
- it "sets the cookbook_name attribute to the value of the :name option if given" do
19
- subject.from_path(cookbook_path, name: "rspec_tester").cookbook_name.should eql("rspec_tester")
20
- end
21
-
22
18
  context "given a path that does not contain a metadata file" do
23
19
  it "raises an IOError" do
24
20
  lambda {
@@ -35,8 +31,10 @@ describe Ridley::Chef::Cookbook do
35
31
  FileUtils.touch(File.join(cookbook_path, 'metadata.rb'))
36
32
  end
37
33
 
38
- it "sets the name of the cookbook to the name of the directory containing it" do
39
- subject.from_path(cookbook_path).cookbook_name.should eql("directory_name")
34
+ it "raises an exception" do
35
+ expect {
36
+ subject.from_path(cookbook_path)
37
+ }.to raise_error(Ridley::Errors::MissingNameAttribute)
40
38
  end
41
39
  end
42
40
 
@@ -158,7 +156,14 @@ describe Ridley::Chef::Cookbook do
158
156
  end
159
157
 
160
158
  context "when a metadata.json file is not present" do
161
- before { FileUtils.rm_f(File.join(cookbook_path, "metadata.json")) }
159
+ before do
160
+ FileUtils.rm_f(File.join(cookbook_path, 'metadata.json'))
161
+
162
+ File.open(File.join(cookbook_path, 'metadata.rb'), 'w+') do |f|
163
+ f.write "name 'cookbook'"
164
+ end
165
+ end
166
+
162
167
  its(:compiled_metadata?) { should be_false }
163
168
  end
164
169
  end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ module Ridley
4
+ describe Mixin::FromFile do
5
+ describe '.from_file' do
6
+ context 'when there is bad Ruby in the file' do
7
+ let(:instance) { Class.new { include Ridley::Mixin::FromFile }.new }
8
+
9
+ before do
10
+ File.stub(:exists?).and_return(true)
11
+ File.stub(:readable?).and_return(true)
12
+ IO.stub(:read).and_return('invalid Ruby code')
13
+ end
14
+
15
+ it 'raises a FromFileParserError' do
16
+ expect {
17
+ instance.from_file('/path')
18
+ }.to raise_error(Errors::FromFileParserError)
19
+ end
20
+
21
+ it 'includes the backtrace from the original error' do
22
+ expect { instance.from_file('/path') }.to raise_error { |error|
23
+ expect(error.message).to include("undefined local variable or method `code' for")
24
+ expect(error.backtrace).to include("/path:1:in `block in from_file'")
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ridley
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.1
4
+ version: 3.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamie Winsor
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-17 00:00:00.000000000 Z
12
+ date: 2014-04-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable
@@ -101,28 +101,28 @@ dependencies:
101
101
  requirements:
102
102
  - - ~>
103
103
  - !ruby/object:Gem::Version
104
- version: '0.15'
104
+ version: 0.16.0.pre
105
105
  type: :runtime
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - ~>
110
110
  - !ruby/object:Gem::Version
111
- version: '0.15'
111
+ version: 0.16.0.pre
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: celluloid-io
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - ~>
117
117
  - !ruby/object:Gem::Version
118
- version: '0.15'
118
+ version: 0.16.0.pre
119
119
  type: :runtime
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - ~>
124
124
  - !ruby/object:Gem::Version
125
- version: '0.15'
125
+ version: 0.16.0.pre
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: erubis
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -143,14 +143,14 @@ dependencies:
143
143
  requirements:
144
144
  - - ~>
145
145
  - !ruby/object:Gem::Version
146
- version: 0.8.4
146
+ version: 0.9.0
147
147
  type: :runtime
148
148
  prerelease: false
149
149
  version_requirements: !ruby/object:Gem::Requirement
150
150
  requirements:
151
151
  - - ~>
152
152
  - !ruby/object:Gem::Version
153
- version: 0.8.4
153
+ version: 0.9.0
154
154
  - !ruby/object:Gem::Dependency
155
155
  name: hashie
156
156
  requirement: !ruby/object:Gem::Requirement
@@ -304,7 +304,6 @@ files:
304
304
  - lib/ridley/middleware/follow_redirects.rb
305
305
  - lib/ridley/middleware/gzip.rb
306
306
  - lib/ridley/middleware/parse_json.rb
307
- - lib/ridley/middleware/retry.rb
308
307
  - lib/ridley/mixin.rb
309
308
  - lib/ridley/mixin/checksum.rb
310
309
  - lib/ridley/mixin/from_file.rb
@@ -388,6 +387,7 @@ files:
388
387
  - spec/unit/ridley/middleware/chef_response_spec.rb
389
388
  - spec/unit/ridley/middleware/gzip_spec.rb
390
389
  - spec/unit/ridley/middleware/parse_json_spec.rb
390
+ - spec/unit/ridley/mixins/from_file_spec.rb
391
391
  - spec/unit/ridley/resource_spec.rb
392
392
  - spec/unit/ridley/resources/client_resource_spec.rb
393
393
  - spec/unit/ridley/resources/cookbook_resource_spec.rb
@@ -416,9 +416,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
416
416
  version: 1.9.1
417
417
  required_rubygems_version: !ruby/object:Gem::Requirement
418
418
  requirements:
419
- - - '>='
419
+ - - '>'
420
420
  - !ruby/object:Gem::Version
421
- version: '0'
421
+ version: 1.3.1
422
422
  requirements: []
423
423
  rubyforge_project:
424
424
  rubygems_version: 2.0.14
@@ -488,6 +488,7 @@ test_files:
488
488
  - spec/unit/ridley/middleware/chef_response_spec.rb
489
489
  - spec/unit/ridley/middleware/gzip_spec.rb
490
490
  - spec/unit/ridley/middleware/parse_json_spec.rb
491
+ - spec/unit/ridley/mixins/from_file_spec.rb
491
492
  - spec/unit/ridley/resource_spec.rb
492
493
  - spec/unit/ridley/resources/client_resource_spec.rb
493
494
  - spec/unit/ridley/resources/cookbook_resource_spec.rb
@@ -1,60 +0,0 @@
1
- module Ridley
2
- # Catches exceptions and retries each request a limited number of times.
3
- #
4
- # @example
5
- #
6
- # Faraday.new do |conn|
7
- # conn.request :retry, max: 2, interval: 0.05, exceptions: [CustomException, Faraday::Timeout::Error]
8
- # conn.adapter ...
9
- # end
10
- #
11
- # @note Borrowed and modified from: {https://github.com/lostisland/faraday/blob/master/lib/faraday/request/retry.rb}
12
- # use the Faraday official middleware after the release of 0.9.x
13
- class Middleware::Retry < Faraday::Middleware
14
- # @option options [Integer] :max
15
- # maximum number of retries
16
- # @option options [Float] :interval
17
- # pause in seconds between retries
18
- # @option options [Array] :exceptions
19
- # the list of exceptions to handle
20
- def initialize(app, options = {})
21
- super(app)
22
- @options = options.slice(:max, :interval, :exceptions)
23
- @errmatch = build_exception_matcher(@options[:exceptions])
24
- end
25
-
26
- def call(env)
27
- retries = @options[:max]
28
- begin
29
- @app.call(env)
30
- rescue @errmatch
31
- if retries > 0
32
- retries -= 1
33
- sleep @options[:interval] if @options[:interval] > 0
34
- retry
35
- end
36
- raise
37
- end
38
- end
39
-
40
- # construct an exception matcher object.
41
- #
42
- # An exception matcher for the rescue clause can usually be any object that
43
- # responds to `===`, but for Ruby 1.8 it has to be a Class or Module.
44
- def build_exception_matcher(exceptions)
45
- matcher = Module.new
46
- (class << matcher; self; end).class_eval do
47
- define_method(:===) do |error|
48
- exceptions.any? do |ex|
49
- if ex.is_a? Module then error.is_a? ex
50
- else error.class.to_s == ex.to_s
51
- end
52
- end
53
- end
54
- end
55
- matcher
56
- end
57
- end
58
- end
59
-
60
- Faraday.register_middleware(:request, retry: Ridley::Middleware::Retry)