loquor 1.11.0 → 1.12.0
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 +8 -8
- data/CHANGELOG.md +3 -0
- data/lib/loquor/configuration.rb +4 -1
- data/lib/loquor/http_action.rb +27 -1
- data/lib/loquor/version.rb +1 -1
- data/test/http_action_test.rb +88 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NDMwODdkODY4NWMwY2ViZjkzOGE4MTczNTU1MGYwYjFiOTMwNmI2Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YTczMjQwNDQ1ZTdiZThkOTE2YWYyNWEzNTIyZDA3Zjc4ZTZiNDgxNA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ODdmZDYyYTJlY2MwMGMzN2YxZjNmZTlkMjQ4OWMxNTI2ZWNhODI4NzI4MDQ3
|
10
|
+
MjlmMTdhNGIyNmU5YTZiMTZjMjNiNThkYzBkYTkzYTliN2RiNTkxNzQ1NmJi
|
11
|
+
ZjZkNmEyZmI3NTczZWUwMDBmYjViOWY0YjRjMWU4OGUwNTE0YmU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZGMyOTNhOWFkZjNlYTU1ODY4NzgyYTZkYTc4YzU5ODk1MjA1Y2Q3MjRiNGU4
|
14
|
+
ZTU3MjIwNWZkNDk1MWQ5ZDQyZWRlYWViZTVjNDA3YWRmOWQ1NGYwNWQyM2Ji
|
15
|
+
ZDA0ZWY5ZTRlMmVkZjJiMTRkYzczZTg0MDBjMTFmMzEzYTkxYzE=
|
data/CHANGELOG.md
CHANGED
data/lib/loquor/configuration.rb
CHANGED
@@ -7,7 +7,7 @@ module Loquor
|
|
7
7
|
class Configuration
|
8
8
|
|
9
9
|
SETTINGS = [
|
10
|
-
:logger, :access_id, :secret_key, :endpoint, :substitute_values, :retry_404s
|
10
|
+
:logger, :access_id, :secret_key, :endpoint, :substitute_values, :retry_404s, :retry_503s, :max_retries, :retry_backoff
|
11
11
|
]
|
12
12
|
|
13
13
|
attr_writer *SETTINGS
|
@@ -17,6 +17,9 @@ module Loquor
|
|
17
17
|
self.logger = Filum.logger
|
18
18
|
self.substitute_values = {}
|
19
19
|
self.retry_404s = false
|
20
|
+
self.retry_503s = true
|
21
|
+
self.max_retries = 5
|
22
|
+
self.retry_backoff = 2
|
20
23
|
end
|
21
24
|
|
22
25
|
SETTINGS.each do |setting|
|
data/lib/loquor/http_action.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
|
1
3
|
module Loquor
|
2
4
|
class HttpAction
|
3
5
|
def initialize(url, deps)
|
4
6
|
@url = url
|
5
7
|
@config = deps[:config]
|
6
8
|
@should_cache = deps[:should_cache]
|
9
|
+
@retry_count = 0
|
7
10
|
end
|
8
11
|
|
9
12
|
def signed_request
|
10
13
|
req = request
|
11
14
|
@config.logger.info "Setting user-agent."
|
12
|
-
req.headers['User-Agent'] =
|
15
|
+
req.headers['User-Agent'] = user_agent
|
13
16
|
@config.logger.info "Signing request."
|
14
17
|
ApiAuth.sign!(req, @config.access_id, @config.secret_key)
|
15
18
|
end
|
@@ -17,6 +20,17 @@ module Loquor
|
|
17
20
|
def execute
|
18
21
|
@config.logger.info "Making HTTP request to: #{full_url}"
|
19
22
|
signed_request.execute
|
23
|
+
rescue RestClient::ServiceUnavailable => e
|
24
|
+
@config.logger.error("503 received for request to #{@url}.")
|
25
|
+
@retry_count += 1
|
26
|
+
if should_retry
|
27
|
+
@config.logger.error("Retrying (retry attempt #{@retry_count})")
|
28
|
+
back_off(@config.retry_backoff ** @retry_count)
|
29
|
+
retry
|
30
|
+
else
|
31
|
+
@config.logger.error("Abandoning request (service unavailable)")
|
32
|
+
raise e
|
33
|
+
end
|
20
34
|
rescue RestClient::ResourceNotFound => e
|
21
35
|
@config.logger.error("HTTP 404 when accessing #{full_url}")
|
22
36
|
raise
|
@@ -25,11 +39,23 @@ module Loquor
|
|
25
39
|
raise
|
26
40
|
end
|
27
41
|
|
42
|
+
def back_off(delay)
|
43
|
+
sleep(delay)
|
44
|
+
end
|
45
|
+
|
28
46
|
private
|
29
47
|
|
48
|
+
def should_retry
|
49
|
+
@config.retry_503s && @retry_count < @config.max_retries
|
50
|
+
end
|
51
|
+
|
30
52
|
def full_url
|
31
53
|
"#{@config.endpoint}#{@url}"
|
32
54
|
end
|
55
|
+
|
56
|
+
def user_agent
|
57
|
+
"Loquor-#{VERSION}/#{@config.access_id}"
|
58
|
+
end
|
33
59
|
end
|
34
60
|
end
|
35
61
|
|
data/lib/loquor/version.rb
CHANGED
data/test/http_action_test.rb
CHANGED
@@ -11,6 +11,7 @@ module Loquor
|
|
11
11
|
def deps
|
12
12
|
logger = mock()
|
13
13
|
logger.stubs(info: nil)
|
14
|
+
logger.stubs(error: nil)
|
14
15
|
|
15
16
|
config = mock()
|
16
17
|
config.stubs(logger: logger)
|
@@ -18,6 +19,9 @@ module Loquor
|
|
18
19
|
config.stubs(secret_key: @secret_key)
|
19
20
|
config.stubs(endpoint: @endpoint)
|
20
21
|
config.stubs(cache: @cache)
|
22
|
+
config.stubs(retry_backoff: 2)
|
23
|
+
config.stubs(max_retries: 5)
|
24
|
+
config.stubs(retry_503s: true)
|
21
25
|
{config: config}
|
22
26
|
end
|
23
27
|
|
@@ -27,5 +31,89 @@ module Loquor
|
|
27
31
|
action.expects(signed_request: mock(execute: json))
|
28
32
|
assert_equal json, action.send(:execute)
|
29
33
|
end
|
34
|
+
|
35
|
+
def test_execute_retries_on_503
|
36
|
+
json = "{}"
|
37
|
+
|
38
|
+
r = mock()
|
39
|
+
r.stubs(:execute).raises(RestClient::ServiceUnavailable.new)
|
40
|
+
.then.raises(RestClient::ServiceUnavailable.new).then.returns(json)
|
41
|
+
|
42
|
+
action = HttpAction.new("", deps)
|
43
|
+
action.expects(signed_request: r).times(3)
|
44
|
+
action.expects(:back_off).with(2)
|
45
|
+
action.expects(:back_off).with(4)
|
46
|
+
|
47
|
+
assert_equal json, action.send(:execute)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_disable_503_retries
|
51
|
+
my_deps = deps
|
52
|
+
my_deps[:config].stubs(retry_503s: false)
|
53
|
+
|
54
|
+
r = mock()
|
55
|
+
r.stubs(:execute).raises(RestClient::ServiceUnavailable.new)
|
56
|
+
|
57
|
+
action = HttpAction.new("", my_deps)
|
58
|
+
action.expects(signed_request: r)
|
59
|
+
|
60
|
+
assert_raises RestClient::ServiceUnavailable do
|
61
|
+
action.send(:execute)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_execute_rethrows_503_when_retry_count_exceeded
|
66
|
+
r = mock()
|
67
|
+
r.stubs(:execute).raises(RestClient::ServiceUnavailable.new).times(5)
|
68
|
+
|
69
|
+
action = HttpAction.new("", deps)
|
70
|
+
action.expects(signed_request: r).times(5)
|
71
|
+
action.expects(:back_off).with(2)
|
72
|
+
action.expects(:back_off).with(4)
|
73
|
+
action.expects(:back_off).with(8)
|
74
|
+
action.expects(:back_off).with(16)
|
75
|
+
|
76
|
+
assert_raises RestClient::ServiceUnavailable do
|
77
|
+
action.send(:execute)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_execute_rethrows_503_with_configurable_backoff_and_max_retries
|
82
|
+
my_deps = deps
|
83
|
+
my_deps[:config].stubs(retry_backoff: 3)
|
84
|
+
my_deps[:config].stubs(max_retries: 4)
|
85
|
+
|
86
|
+
r = mock()
|
87
|
+
r.stubs(:execute).raises(RestClient::ServiceUnavailable.new).times(4)
|
88
|
+
|
89
|
+
action = HttpAction.new("", my_deps)
|
90
|
+
action.expects(signed_request: r).times(4)
|
91
|
+
action.expects(:back_off).with(3)
|
92
|
+
action.expects(:back_off).with(9)
|
93
|
+
action.expects(:back_off).with(27)
|
94
|
+
|
95
|
+
assert_raises RestClient::ServiceUnavailable do
|
96
|
+
action.send(:execute)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_execute_rethrows_404
|
101
|
+
err = RestClient::ResourceNotFound.new
|
102
|
+
|
103
|
+
r = mock()
|
104
|
+
r.stubs(:execute).raises(err)
|
105
|
+
|
106
|
+
action = HttpAction.new("", deps)
|
107
|
+
action.expects(signed_request: r)
|
108
|
+
|
109
|
+
assert_raises RestClient::ResourceNotFound do
|
110
|
+
action.send(:execute)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_user_agent
|
115
|
+
action = HttpAction.new("", deps)
|
116
|
+
assert /Loquor-\d+.\d+.\d+\/123/.match(action.send(:user_agent))
|
117
|
+
end
|
30
118
|
end
|
31
119
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loquor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Walker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: filum
|