record_store 6.3.0 → 6.3.1

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: 6476b30f3ef1df05642b1645783e2186e8ca6a3f489d99c4724fb252d6b26b97
4
- data.tar.gz: 84ddb2d0e34076198bc1df633ab51714253c8c4ced05ef8b5b60eb777714eacb
3
+ metadata.gz: f6875c27f0cf86510b733a58f668d44560eeb40e7c8b6c9438183fee175bc514
4
+ data.tar.gz: 3599cc9903a5afe46d544f8aeef349961fdc2d95011973325bbdcc75972c56c5
5
5
  SHA512:
6
- metadata.gz: '01136420252835b0ce65abf03d0466f88f879cf52c55f1db5e3db0753121bd55610c78fec31ee552b0d95c02b1922e8aefd4d91679872b1f16af16188fff0cde'
7
- data.tar.gz: 512eb4f464314c298c07367e52dc9a3e6cec126da174f19c52cd4d32c12be7ab1d1a565c653b6f853a346582db9076e078ee530914272c1fbf6317306c911176
6
+ metadata.gz: 9a6def9342919457cc71fdda4691c92310450dfc28a476eee6d353b73798b8d1b612b4775982704b0c44b2e657149a02f0e96330796b03d591619ad5930509ae
7
+ data.tar.gz: 42183ae0ecd31e27a2d40977ecdda6cb51c0368ff24ac3a2de4411ab016809c5551ee3faeb50eb53503be059ece4bc41889e6c73d3e1f0ab53e7ab9290563628
@@ -1,5 +1,8 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 6.3.1
4
+ - Improve resiliency in the face of temporary provider outages [BUGFIX]
5
+
3
6
  ## 6.3.0
4
7
  - Support for configurable number of threads via environment variable [FEATURE]
5
8
 
@@ -2,6 +2,9 @@ require 'resolv'
2
2
 
3
3
  module RecordStore
4
4
  class Provider
5
+ class Error < StandardError; end
6
+ class UnparseableBodyError < Error; end
7
+
5
8
  class << self
6
9
  def provider_for(object)
7
10
  ns_server =
@@ -136,12 +139,13 @@ module RecordStore
136
139
  def retry_on_connection_errors(
137
140
  max_timeouts: 5,
138
141
  max_conn_resets: 5,
142
+ max_retries: 5,
139
143
  delay: 1,
140
144
  backoff_multiplier: 2,
141
145
  max_backoff: 10
142
146
  )
143
147
  waiter = BackoffWaiter.new(
144
- "Waiting to retry after a connection reset",
148
+ 'Waiting to retry after a connection reset',
145
149
  initial_delay: delay,
146
150
  multiplier: backoff_multiplier,
147
151
  max_delay: max_backoff,
@@ -150,11 +154,16 @@ module RecordStore
150
154
  loop do
151
155
  begin
152
156
  return yield
157
+ rescue UnparseableBodyError
158
+ raise if max_retries <= 0
159
+ max_retries -= 1
160
+
161
+ waiter.wait(message: 'Waiting to retry after receiving an unparseable response')
153
162
  rescue Net::OpenTimeout, Errno::ETIMEDOUT
154
163
  raise if max_timeouts <= 0
155
164
  max_timeouts -= 1
156
165
 
157
- $stderr.puts("Retrying after a connection timeout")
166
+ $stderr.puts('Retrying after a connection timeout')
158
167
  rescue Errno::ECONNRESET
159
168
  raise if max_conn_resets <= 0
160
169
  max_conn_resets -= 1
@@ -3,8 +3,6 @@ require_relative 'ns1/patch_api_header'
3
3
 
4
4
  module RecordStore
5
5
  class Provider::NS1 < Provider
6
- class Error < StandardError; end
7
-
8
6
  class ApiAnswer
9
7
  class << self
10
8
  def from_full_api_answer(type:, record_id:, answer:)
@@ -180,7 +178,7 @@ module RecordStore
180
178
  unless updated
181
179
  error = +'while trying to update a record, could not find answer with fqdn: '
182
180
  error << "#{record.fqdn}, type; #{record.type}, id: #{id}"
183
- raise Error, error
181
+ raise RecordStore::Provider::Error, error
184
182
  end
185
183
 
186
184
  client.modify_record(
@@ -1,46 +1,59 @@
1
+ require 'net/http'
1
2
  require 'ns1'
2
3
 
3
4
  module RecordStore
4
5
  class Provider::NS1 < Provider
5
- class Error < StandardError; end
6
-
7
6
  class Client < ::NS1::Client
8
7
  def initialize(api_key:)
9
8
  super(api_key)
10
9
  end
11
10
 
12
11
  def zones
13
- super
12
+ zones = super
13
+ raise_if_error!(zones)
14
+ zones
14
15
  end
15
16
 
16
17
  def zone(name)
17
- super(name)
18
+ zone = super(name)
19
+ raise_if_error!(zone)
20
+ zone
18
21
  end
19
22
 
20
23
  def record(zone:, fqdn:, type:, must_exist: false)
21
24
  result = super(zone, fqdn, type)
22
- raise(Error, result.to_s) if must_exist && result.is_a?(NS1::Response::Error)
25
+ raise_if_error!(result) if must_exist
23
26
  return nil if result.is_a?(NS1::Response::Error)
24
27
  result
25
28
  end
26
29
 
27
30
  def create_record(zone:, fqdn:, type:, params:)
28
31
  result = super(zone, fqdn, type, params)
29
- raise(Error, result.to_s) if result.is_a?(NS1::Response::Error)
32
+ raise_if_error!(result)
30
33
  nil
31
34
  end
32
35
 
33
36
  def modify_record(zone:, fqdn:, type:, params:)
34
37
  result = super(zone, fqdn, type, params)
35
- raise(Error, result.to_s) if result.is_a?(NS1::Response::Error)
38
+ raise_if_error!(result)
36
39
  nil
37
40
  end
38
41
 
39
42
  def delete_record(zone:, fqdn:, type:)
40
43
  result = super(zone, fqdn, type)
41
- raise(Error, result.to_s) if result.is_a?(NS1::Response::Error)
44
+ raise_if_error!(result)
42
45
  nil
43
46
  end
47
+
48
+ private
49
+
50
+ def raise_if_error!(result)
51
+ return unless result.is_a?(NS1::Response::Error)
52
+ if result.is_a?(NS1::Response::UnparsableBodyError)
53
+ raise RecordStore::Provider::UnparseableBodyError, result.to_s
54
+ end
55
+ raise RecordStore::Provider::Error, result.to_s
56
+ end
44
57
  end
45
58
  end
46
59
  end
@@ -1,6 +1,13 @@
1
1
  require 'net/http'
2
2
  require_relative '../provider_utils/waiter'
3
3
 
4
+ class NS1::Response::UnparsableBodyError < NS1::Response::Error
5
+ def initialize(status)
6
+ @status = status
7
+ super({}, status)
8
+ end
9
+ end
10
+
4
11
  # Patch the method which retrieves headers for API rate limit dynamically
5
12
  module NS1::Transport
6
13
  class NetHttp
@@ -18,15 +25,17 @@ module NS1::Transport
18
25
  rate_limit.wait(sleep_time)
19
26
  end
20
27
 
21
- body = JSON.parse(response.body)
22
- case response
23
- when Net::HTTPOK
24
- NS1::Response::Success.new(body, response.code.to_i)
25
- else
26
- NS1::Response::Error.new(body, response.code.to_i)
28
+ begin
29
+ body = JSON.parse(response.body)
30
+ case response
31
+ when Net::HTTPOK
32
+ NS1::Response::Success.new(body, response.code.to_i)
33
+ else
34
+ NS1::Response::Error.new(body, response.code.to_i)
35
+ end
36
+ rescue JSON::ParserError
37
+ NS1::Response::UnparsableBodyError.new(response.code.to_i)
27
38
  end
28
- rescue JSON::ParserError
29
- raise NS1::Transport::ResponseParseError
30
39
  end
31
40
  end
32
41
  end
@@ -5,7 +5,7 @@ class Waiter
5
5
 
6
6
  attr_accessor :message
7
7
 
8
- def wait(sleep_time)
8
+ def wait(sleep_time, message: @message)
9
9
  while sleep_time > 0
10
10
  wait_time = [10, sleep_time].min
11
11
  puts "#{message} (#{sleep_time}s left)" if wait_time > 1
@@ -34,8 +34,8 @@ class BackoffWaiter < Waiter
34
34
  @current_delay = @initial_delay
35
35
  end
36
36
 
37
- def wait
38
- super(@current_delay)
37
+ def wait(message: @message)
38
+ super(@current_delay, message: message)
39
39
  @current_delay = [@current_delay * @multiplier, @max_delay].compact.min
40
40
  end
41
41
  end
@@ -1,3 +1,3 @@
1
1
  module RecordStore
2
- VERSION = '6.3.0'.freeze
2
+ VERSION = '6.3.1'.freeze
3
3
  end
@@ -48,6 +48,6 @@ Gem::Specification.new do |spec|
48
48
  spec.add_development_dependency 'vcr'
49
49
  spec.add_development_dependency 'pry'
50
50
  spec.add_development_dependency 'webmock'
51
- spec.add_development_dependency 'rubocop'
51
+ spec.add_development_dependency 'rubocop', '0.89.1'
52
52
  spec.add_development_dependency 'minitest-focus'
53
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: record_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.3.0
4
+ version: 6.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willem van Bergen
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-08-31 00:00:00.000000000 Z
12
+ date: 2020-10-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -301,16 +301,16 @@ dependencies:
301
301
  name: rubocop
302
302
  requirement: !ruby/object:Gem::Requirement
303
303
  requirements:
304
- - - ">="
304
+ - - '='
305
305
  - !ruby/object:Gem::Version
306
- version: '0'
306
+ version: 0.89.1
307
307
  type: :development
308
308
  prerelease: false
309
309
  version_requirements: !ruby/object:Gem::Requirement
310
310
  requirements:
311
- - - ">="
311
+ - - '='
312
312
  - !ruby/object:Gem::Version
313
- version: '0'
313
+ version: 0.89.1
314
314
  - !ruby/object:Gem::Dependency
315
315
  name: minitest-focus
316
316
  requirement: !ruby/object:Gem::Requirement