4me-sdk 1.1.5 → 1.1.6

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: 5709d9ce126fa6349fdff96ab4a2dd1c80b8653a
4
- data.tar.gz: 56ea4d39c7dce6e5c0578f0eb5ab1bbeb154622d
3
+ metadata.gz: 2fb299375b12d3219de2b62186c08d386ab35c15
4
+ data.tar.gz: fec7a3b7d9f0da1bc33845aeb80a909941911428
5
5
  SHA512:
6
- metadata.gz: 754794a8253b590ddfd4064d2d96e9bae96597ab89c0169c6ebdb7fc8db4dd9035e7a0770be6f6644cff362a9f0dc5e061cb3992e15e6502556921bbdd997c5a
7
- data.tar.gz: 80eaad3b45968a8ca3e1ce3afa4a6750c74105ba188122e1bcaf800ea87c64ab63c88893d70ee32793bf8bc19b22a38f5cec830935c153a03ccb978c83fb1607
6
+ metadata.gz: b32a2e7eec8c40b1889ab72555586370bce6080fbff9ea74bc3bd3e7d63709fe456b73b8250a35c7a7f59f30c4755e1a9c1fd79f513372bd611a27965e513330
7
+ data.tar.gz: a8bc3da3ef888716c14d9fe44c75b22c797e4732e52314b6c1efb76c5401661877e1613d311ad675cb400a6755fce0de0f53e9799566f15cab5c4699a3b7e48a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- 4me-sdk (1.1.5)
4
+ 4me-sdk (1.1.6)
5
5
  activesupport (>= 4.2)
6
6
  gem_config (>= 0.3)
7
7
  mime-types (>= 3.0)
data/README.md CHANGED
@@ -37,13 +37,14 @@ All options available:
37
37
  * _api_token_: (**required**) The [4me API token](http://developer.4me.com/v1/#api-tokens)
38
38
  * _account_: Specify a [different account](http://developer.4me.com/v1/#multiple-accounts) to work with
39
39
  * _source_: The [source](http://developer.4me.com/v1/general/source/) used when creating new records
40
- * _max_retry_time_: maximum nr of seconds to wait for server to respond (default = 5400 = 1.5 hours)<br/>
40
+ * _max_retry_time_: maximum nr of seconds to retry a request on a failed response (default = 300 = 5 minutes)<br/>
41
41
  The sleep time between retries starts at 2 seconds and doubles after each retry, i.e.
42
- 2, 6, 18, 54, 162, 486, 1458, 4374, 13122, ... seconds.<br/>
42
+ 2, 6, 18, 54, 162, 486, 1458, ... seconds.<br/>
43
43
  Set to 0 to prevent retries.
44
44
  * _read_timeout_: [HTTP read timeout](http://ruby-doc.org/stdlib-2.0.0/libdoc/net/http/rdoc/Net/HTTP.html#method-i-read_timeout-3D) in seconds (default = 25)
45
- * _block_at_rate_limit_: Set to `true` to block the request until the [rate limit](http://developer.4me.com/v1/#rate-limiting) is lifted, default: `false`<br/>
46
- The `Retry-After` header is used to compute when the retry should be performed. If that moment is later than the _max_retry_time_ the request will not be blocked and the throttled response is returned.
45
+ * _block_at_rate_limit_: Set to `true` to block the request until the [rate limit](http://developer.4me.com/v1/#rate-limiting) is lifted, default: `true`<br/>
46
+ The `Retry-After` header is used to compute when the retry should be performed. If that moment is later than the _max_throttle_time_ the request will not be blocked and the throttled response is returned.
47
+ * _max_throttle_time_: maximum nr of seconds to retry a request on a rate limiter (default = 3660 = 1 hour and 1 minute)<br/>
47
48
  * _proxy_host_: Define in case HTTP traffic needs to go through a proxy
48
49
  * _proxy_port_: Port of the proxy, defaults to 8080
49
50
  * _proxy_user_: Proxy user
@@ -305,10 +306,17 @@ Note that blocking for the export to finish is recommended as you will get direc
305
306
 
306
307
  ### Blocking
307
308
 
308
- By default all actions on the 4me SDK Client will block until the 4me API is accessible, see the _max_retry_time_ option in the [configuration](#configuration). This is especially helpfull for flaky internet connections.
309
+ When the currently used API token hits the [4me rate limiter](http://developer.4me.com/v1/#rate-limiting) a HTTP 429 response is returned that specifies after how many seconds the rate limit will be lifted.
309
310
 
310
- By setting the _block_at_rate_limit_ to `true` in the [configuration](#configuration) all actions will also block in case the [rate limit](http://developer.4me.com/v1/#rate-limiting) is reached. The action is retried every 5 minutes until the [rate limit](http://developer.4me.com/v1/#rate-limiting) is lifted again, which might take up to 1 hour.
311
+ If that time lies within the _max_throttle_time_ the 4me SDK Client will wait and retry the action, if not, the throttled response will be returned. You can verify if a response was throttled using:
312
+ ```
313
+ response = client.get('me')
314
+ puts response.throttled?
315
+ ```
316
+
317
+ By setting the _block_at_rate_limit_ to `false` in the [configuration](#configuration) the 4me SDK Client will never wait when a rate limit is hit.
311
318
 
319
+ Note that 4me has different rate limiters. If the intention is to only wait when the short-burst (max 20 requests in 2 seconds) rate limiter is hit, you could set the _max_throttle_time_ to e.g. 5 seconds.
312
320
 
313
321
  ### Translations
314
322
 
data/lib/sdk4me.rb CHANGED
@@ -14,10 +14,10 @@ module Sdk4me
14
14
  has :account, classes: String
15
15
  has :source, classes: String
16
16
 
17
- has :max_retry_time, classes: Integer, default: 5400
17
+ has :max_retry_time, classes: Integer, default: 300
18
18
  has :read_timeout, classes: Integer, default: 25
19
- has :block_at_rate_limit, classes: [TrueClass, FalseClass], default: false
20
-
19
+ has :block_at_rate_limit, classes: [TrueClass, FalseClass], default: true
20
+ has :max_throttle_time, classes: Integer, default: 3660
21
21
  has :proxy_host, classes: String
22
22
  has :proxy_port, classes: Integer, default: 8080
23
23
  has :proxy_user, classes: String
data/lib/sdk4me/client.rb CHANGED
@@ -300,16 +300,16 @@ module Sdk4me
300
300
  module SendWithRateLimitBlock
301
301
  # Wraps the _send method with retries when the server does not respond, see +initialize+ option +:rate_limit_block+
302
302
  def _send(request, domain = @domain, port = @port, ssl = @ssl)
303
- return super(request, domain, port, ssl) unless option(:block_at_rate_limit)
304
- now = Time.now
303
+ return super(request, domain, port, ssl) unless option(:block_at_rate_limit) && option(:max_throttle_time) > 0
304
+ now = nil
305
305
  timed_out = false
306
- # respect the max_retry_time with fallback to max 1 hour and 1 minute wait time
307
- max_retry_time = option(:max_retry_time) > 0 ? option(:max_retry_time) : 3660
308
306
  begin
309
307
  _response = super(request, domain, port, ssl)
308
+ now ||= Time.now
310
309
  if _response.throttled?
310
+ # if no Retry-After is not provided, the 4me server is very busy, wait 5 minutes
311
311
  retry_after = _response.retry_after == 0 ? 300 : [_response.retry_after, 2].max
312
- if (Time.now - now + retry_after) < max_retry_time
312
+ if (Time.now - now + retry_after) < option(:max_throttle_time)
313
313
  @logger.warn { "Request throttled, trying again in #{retry_after} seconds: #{_response.message}" }
314
314
  sleep(retry_after)
315
315
  else
@@ -328,12 +328,12 @@ module Sdk4me
328
328
  return super(request, domain, port, ssl) unless option(:max_retry_time) > 0
329
329
  retries = 0
330
330
  sleep_time = 1
331
- now = Time.now
331
+ now = nil
332
332
  timed_out = false
333
333
  begin
334
334
  _response = super(request, domain, port, ssl)
335
- # throttling is handled separately
336
- if !_response.success? && !_response.throttled?
335
+ now ||= Time.now
336
+ if _response.failure?
337
337
  sleep_time *= 2
338
338
  if (Time.now - now + sleep_time) < option(:max_retry_time)
339
339
  @logger.warn { "Request failed, retry ##{retries += 1} in #{sleep_time} seconds: #{_response.message}" }
@@ -342,7 +342,7 @@ module Sdk4me
342
342
  timed_out = true
343
343
  end
344
344
  end
345
- end while !_response.success? && !_response.throttled? && !timed_out
345
+ end while _response.failure? && !timed_out
346
346
  _response
347
347
  end
348
348
  end
@@ -59,6 +59,11 @@ module Sdk4me
59
59
  end
60
60
  alias_method :success?, :valid?
61
61
 
62
+ # +true+ in case of a HTTP 5xx error
63
+ def failure?
64
+ !success? && (@response.code.to_s.blank? || @response.code.to_s =~ /5\d\d/)
65
+ end
66
+
62
67
  # retrieve a value from the resource
63
68
  # if the JSON value is an Array a array with the value for each resource will be given
64
69
  # @param keys: a single key or a key-path separated by comma
@@ -1,5 +1,5 @@
1
1
  module Sdk4me
2
2
  class Client
3
- VERSION = '1.1.5'
3
+ VERSION = '1.1.6'
4
4
  end
5
5
  end
@@ -528,7 +528,7 @@ describe Sdk4me::Client do
528
528
  expect_log('Sending GET request to api.4me.com:443/v1/me', :debug )
529
529
  expect_log(%(Response:\n{\n "name": "my name"\n}), :debug )
530
530
 
531
- client = Sdk4me::Client.new(api_token: 'secret', block_at_rate_limit: true)
531
+ client = Sdk4me::Client.new(api_token: 'secret', block_at_rate_limit: true, max_retry_time: 500)
532
532
  allow(client).to receive(:sleep)
533
533
  response = client.get('me')
534
534
  expect(stub).to have_been_requested.times(2)
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Sdk4me::Response do
4
4
  before(:each) do
5
- @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
5
+ @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1, block_at_rate_limit: false)
6
6
  @person_hash = {
7
7
  addresses:[],
8
8
  contacts:[ {id: 1365, label: 'work', telephone: '7139872946'} ],
@@ -22,7 +22,6 @@ describe Sdk4me::Response do
22
22
  stub_request(:get, 'https://api.4me.com/v1/me').with(basic_auth: ['secret', 'x']).to_return(body: @person_hash.to_json)
23
23
  @response_hash = @client.get('me')
24
24
 
25
- @client = Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
26
25
  @people_array = [
27
26
  {id: 562, name: 'John', organization: { id: 20, name: 'SDK4ME Institute'}, site: {id: 14, name: 'IT Training Facility'} },
28
27
  {id: 560, name: 'Lucas', organization: { id: 20, name: 'SDK4ME Institute', office: { name: 'The Office'}}, site: {id: 14, name: 'IT Training Facility'} },
@@ -4,15 +4,15 @@ describe Sdk4me do
4
4
  it "should define a default configuration" do
5
5
  conf = Sdk4me.configuration.current
6
6
 
7
- expect(conf.keys.sort).to eq([:account, :api_token, :api_version, :block_at_rate_limit, :ca_file, :host, :logger, :max_retry_time, :proxy_host, :proxy_password, :proxy_port, :proxy_user, :read_timeout, :source])
7
+ expect(conf.keys.sort).to eq([:account, :api_token, :api_version, :block_at_rate_limit, :ca_file, :host, :logger, :max_retry_time, :max_throttle_time, :proxy_host, :proxy_password, :proxy_port, :proxy_user, :read_timeout, :source])
8
8
 
9
9
  expect(conf[:logger].class).to eq(::Logger)
10
10
  expect(conf[:host]).to eq('https://api.4me.com')
11
11
  expect(conf[:api_version]).to eq('v1')
12
12
 
13
- expect(conf[:max_retry_time]).to eq(5400)
13
+ expect(conf[:max_retry_time]).to eq(300)
14
14
  expect(conf[:read_timeout]).to eq(25)
15
- expect(conf[:block_at_rate_limit]).to be_falsey
15
+ expect(conf[:block_at_rate_limit]).to be_truthy
16
16
 
17
17
  expect(conf[:proxy_port]).to eq(8080)
18
18
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 4me-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - 4me
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-10 00:00:00.000000000 Z
11
+ date: 2019-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_config