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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +14 -6
- data/lib/sdk4me.rb +3 -3
- data/lib/sdk4me/client.rb +9 -9
- data/lib/sdk4me/client/response.rb +5 -0
- data/lib/sdk4me/client/version.rb +1 -1
- data/spec/lib/sdk4me/client_spec.rb +1 -1
- data/spec/lib/sdk4me/response_spec.rb +1 -2
- data/spec/lib/sdk4me_spec.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fb299375b12d3219de2b62186c08d386ab35c15
|
4
|
+
data.tar.gz: fec7a3b7d9f0da1bc33845aeb80a909941911428
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b32a2e7eec8c40b1889ab72555586370bce6080fbff9ea74bc3bd3e7d63709fe456b73b8250a35c7a7f59f30c4755e1a9c1fd79f513372bd611a27965e513330
|
7
|
+
data.tar.gz: a8bc3da3ef888716c14d9fe44c75b22c797e4732e52314b6c1efb76c5401661877e1613d311ad675cb400a6755fce0de0f53e9799566f15cab5c4699a3b7e48a
|
data/Gemfile.lock
CHANGED
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
|
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,
|
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: `
|
46
|
-
The `Retry-After` header is used to compute when the retry should be performed. If that moment is later than the
|
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
|
-
|
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
|
-
|
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:
|
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:
|
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 =
|
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) <
|
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 =
|
331
|
+
now = nil
|
332
332
|
timed_out = false
|
333
333
|
begin
|
334
334
|
_response = super(request, domain, port, ssl)
|
335
|
-
|
336
|
-
if
|
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
|
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
|
@@ -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'} },
|
data/spec/lib/sdk4me_spec.rb
CHANGED
@@ -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(
|
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
|
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.
|
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-
|
11
|
+
date: 2019-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gem_config
|