saddle 0.0.27 → 0.0.30
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.
- data/lib/saddle.rb +4 -7
- data/lib/saddle/middleware/request/retry.rb +10 -7
- data/lib/saddle/middleware/request/user_agent.rb +29 -0
- data/lib/saddle/middleware/response/default_response.rb +1 -1
- data/lib/saddle/middleware/ruby_timeout.rb +1 -1
- data/lib/saddle/requester.rb +12 -8
- data/lib/saddle/version.rb +1 -1
- data/spec/middleware/request/retry_spec.rb +87 -35
- data/spec/middleware/response/default_response_spec.rb +44 -0
- metadata +4 -1
data/lib/saddle.rb
CHANGED
@@ -2,6 +2,7 @@ require 'saddle/client_attributes'
|
|
2
2
|
require 'saddle/method_tree_builder'
|
3
3
|
require 'saddle/options'
|
4
4
|
require 'saddle/requester'
|
5
|
+
require 'saddle/version'
|
5
6
|
|
6
7
|
|
7
8
|
# Inherit your client implementation from Saddle::Client
|
@@ -16,7 +17,7 @@ module Saddle
|
|
16
17
|
extend Options
|
17
18
|
|
18
19
|
class << self
|
19
|
-
attr_accessor :additional_middlewares
|
20
|
+
attr_accessor :additional_middlewares, :parent_module
|
20
21
|
|
21
22
|
# Once your implementation is written, this is the magic you need to
|
22
23
|
# create a client instance.
|
@@ -38,12 +39,8 @@ module Saddle
|
|
38
39
|
end
|
39
40
|
# Add additional client attributes
|
40
41
|
obj.send(:include, Saddle::ClientAttributes)
|
41
|
-
|
42
|
-
|
43
|
-
# Name of the module that contains the implementing client
|
44
|
-
def root_namespace
|
45
|
-
module_nests = self.name.split('::')
|
46
|
-
module_nests.length > 1 ? module_nests[-2] : module_nests.last
|
42
|
+
# Store the parent module in case we need it later
|
43
|
+
@parent_module = Module.nesting.last
|
47
44
|
end
|
48
45
|
|
49
46
|
end
|
@@ -22,13 +22,16 @@ module Saddle
|
|
22
22
|
begin
|
23
23
|
@app.call(self.class.deep_copy(env))
|
24
24
|
rescue => e
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
# Only retry for GET or if the request is marked as idempotent
|
26
|
+
if env[:method] == :get || env[:request][:idempotent]
|
27
|
+
unless @ignored_exceptions.include?(e.class)
|
28
|
+
# Retry a limited number of times
|
29
|
+
if retries > 0
|
30
|
+
retries -= 1
|
31
|
+
sleep(backoff) if backoff > 0.0
|
32
|
+
backoff *= 2
|
33
|
+
retry
|
34
|
+
end
|
32
35
|
end
|
33
36
|
end
|
34
37
|
# Re-raise if we're out of retries or it's not handled
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
module Saddle
|
6
|
+
module Middleware
|
7
|
+
module Request
|
8
|
+
|
9
|
+
# Public: Adds a user-agent to the request
|
10
|
+
|
11
|
+
class UserAgent < Faraday::Middleware
|
12
|
+
def call(env)
|
13
|
+
# Build a user agent that looks like 'SaddleExample 0.0.1'
|
14
|
+
user_agent = env[:request][:saddle][:client].name
|
15
|
+
if env[:request][:saddle][:client].parent_module
|
16
|
+
if defined?(env[:request][:saddle][:client].parent_module::VERSION)
|
17
|
+
user_agent += " #{env[:request][:saddle][:client].parent_module::VERSION}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
env[:request_headers]['User-Agent'] = user_agent
|
22
|
+
|
23
|
+
@app.call env
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -13,7 +13,7 @@ module Saddle
|
|
13
13
|
class RubyTimeout < Faraday::Middleware
|
14
14
|
|
15
15
|
def call(env)
|
16
|
-
timeout = env[:request][:
|
16
|
+
timeout = env[:request][:hard_timeout] # nil or 0 means no timeout
|
17
17
|
Timeout.timeout(timeout, Saddle::TimeoutError) do
|
18
18
|
@app.call(env)
|
19
19
|
end
|
data/lib/saddle/requester.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
require 'faraday'
|
2
2
|
require 'faraday_middleware'
|
3
3
|
|
4
|
+
|
4
5
|
require 'saddle/middleware/request/encode_json'
|
5
6
|
require 'saddle/middleware/request/path_prefix'
|
6
7
|
require 'saddle/middleware/request/retry'
|
7
8
|
require 'saddle/middleware/request/url_encoded'
|
9
|
+
require 'saddle/middleware/request/user_agent'
|
10
|
+
|
8
11
|
require 'saddle/middleware/response/default_response'
|
9
12
|
require 'saddle/middleware/response/parse_json'
|
13
|
+
|
10
14
|
require 'saddle/middleware/ruby_timeout'
|
11
15
|
|
12
16
|
|
@@ -123,8 +127,11 @@ module Saddle
|
|
123
127
|
builder.options[:num_retries] = @num_retries
|
124
128
|
end
|
125
129
|
|
126
|
-
#
|
127
|
-
builder.
|
130
|
+
# Hard timeout on the entire request
|
131
|
+
builder.use(Saddle::Middleware::RubyTimeout)
|
132
|
+
|
133
|
+
# Set up a user agent
|
134
|
+
builder.use(Saddle::Middleware::Request::UserAgent)
|
128
135
|
|
129
136
|
# Set up the path prefix if needed
|
130
137
|
builder.use(Saddle::Middleware::Request::PathPrefix)
|
@@ -137,19 +144,16 @@ module Saddle
|
|
137
144
|
builder.use(m[:klass], *m[:args])
|
138
145
|
end
|
139
146
|
|
140
|
-
# Hard timeout on the entire request
|
141
|
-
builder.use(Saddle::Middleware::RubyTimeout)
|
142
|
-
|
143
147
|
# Request encoding
|
144
148
|
builder.use(Saddle::Middleware::Request::JsonEncoded)
|
145
149
|
builder.use(Saddle::Middleware::Request::UrlEncoded)
|
146
150
|
|
147
|
-
# Automatic retries
|
148
|
-
builder.use(Saddle::Middleware::Request::Retry)
|
149
|
-
|
150
151
|
# Handle parsing out the response if it's JSON
|
151
152
|
builder.use(Saddle::Middleware::Response::ParseJson)
|
152
153
|
|
154
|
+
# Automatic retries
|
155
|
+
builder.use(Saddle::Middleware::Request::Retry)
|
156
|
+
|
153
157
|
# Raise exceptions on 4xx and 5xx errors
|
154
158
|
builder.use(Faraday::Response::RaiseError)
|
155
159
|
|
data/lib/saddle/version.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'faraday'
|
1
2
|
require 'saddle'
|
2
3
|
|
3
4
|
|
@@ -12,43 +13,94 @@ describe Saddle::Client do
|
|
12
13
|
@default_client = Saddle::Client.create(:stubs => @stubs)
|
13
14
|
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
16
|
+
context "for a GET request" do
|
17
|
+
it "with no params should properly retry" do
|
18
|
+
url = '/test'
|
19
|
+
@stubs.get(url) {
|
20
|
+
[
|
21
|
+
500,
|
22
|
+
{},
|
23
|
+
'Failure',
|
24
|
+
]
|
25
|
+
}
|
26
|
+
@stubs.get(url) {
|
27
|
+
[
|
28
|
+
200,
|
29
|
+
{},
|
30
|
+
'Party!',
|
31
|
+
]
|
32
|
+
}
|
33
|
+
@default_client.requester.get(url).should == 'Party!'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "with params should properly retry" do
|
37
|
+
url = '/test?a=1'
|
38
|
+
@stubs.get(url) {
|
39
|
+
[
|
40
|
+
500,
|
41
|
+
{},
|
42
|
+
'Failure',
|
43
|
+
]
|
44
|
+
}
|
45
|
+
@stubs.get(url) {
|
46
|
+
[
|
47
|
+
200,
|
48
|
+
{},
|
49
|
+
'Party!',
|
50
|
+
]
|
51
|
+
}
|
52
|
+
@default_client.requester.get(url).should == 'Party!'
|
53
|
+
end
|
31
54
|
end
|
32
55
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
56
|
+
|
57
|
+
|
58
|
+
context "for a POST request" do
|
59
|
+
it "should not retry" do
|
60
|
+
url = '/test'
|
61
|
+
@stubs.post(url) {
|
62
|
+
[
|
63
|
+
500,
|
64
|
+
{},
|
65
|
+
'Failure',
|
66
|
+
]
|
67
|
+
}
|
68
|
+
@stubs.post(url) {
|
69
|
+
[
|
70
|
+
200,
|
71
|
+
{},
|
72
|
+
'Party!',
|
73
|
+
]
|
74
|
+
}
|
75
|
+
expect {
|
76
|
+
@default_client.requester.post(url)
|
77
|
+
}.to raise_error(Faraday::Error::ClientError)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should retry if it is marked as idempotent" do
|
81
|
+
url = '/test'
|
82
|
+
params = {'a' => 1, 'b' => 2}
|
83
|
+
params_json = params.to_json
|
84
|
+
@stubs.post(url, params_json) {
|
85
|
+
[
|
86
|
+
500,
|
87
|
+
{},
|
88
|
+
'Failure',
|
89
|
+
]
|
90
|
+
}
|
91
|
+
@stubs.post(url, params_json) {
|
92
|
+
[
|
93
|
+
200,
|
94
|
+
{},
|
95
|
+
'Party!',
|
96
|
+
]
|
97
|
+
}
|
98
|
+
@default_client.requester.post(
|
99
|
+
url,
|
100
|
+
params,
|
101
|
+
{:idempotent => true}
|
102
|
+
).should == 'Party!'
|
103
|
+
end
|
52
104
|
end
|
53
105
|
|
54
106
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'saddle'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
describe Saddle::Client do
|
6
|
+
|
7
|
+
context "Default response requests" do
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
@stubs = Faraday::Adapter::Test::Stubs.new
|
11
|
+
@default_client = Saddle::Client.create(:stubs => @stubs)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return as normal upon success" do
|
15
|
+
@stubs.get('/test') {
|
16
|
+
[
|
17
|
+
200,
|
18
|
+
{},
|
19
|
+
'Party!',
|
20
|
+
]
|
21
|
+
}
|
22
|
+
@default_client.requester.get(
|
23
|
+
'/test',
|
24
|
+
{},
|
25
|
+
{:default_response => 'Not a party.'}
|
26
|
+
).should == 'Party!'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return the default response upon failure" do
|
30
|
+
@stubs.get('/test') {
|
31
|
+
[
|
32
|
+
500,
|
33
|
+
{},
|
34
|
+
'Failure',
|
35
|
+
]
|
36
|
+
}
|
37
|
+
@default_client.requester.get(
|
38
|
+
'/test',
|
39
|
+
{},
|
40
|
+
{:default_response => 'Not a party.'}
|
41
|
+
).should == 'Not a party.'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saddle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.30
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -83,6 +83,7 @@ files:
|
|
83
83
|
- lib/saddle/middleware/request/path_prefix.rb
|
84
84
|
- lib/saddle/middleware/request/retry.rb
|
85
85
|
- lib/saddle/middleware/request/url_encoded.rb
|
86
|
+
- lib/saddle/middleware/request/user_agent.rb
|
86
87
|
- lib/saddle/middleware/response/default_response.rb
|
87
88
|
- lib/saddle/middleware/response/parse_json.rb
|
88
89
|
- lib/saddle/middleware/ruby_timeout.rb
|
@@ -95,6 +96,7 @@ files:
|
|
95
96
|
- spec/middleware/logging/rails_spec.rb
|
96
97
|
- spec/middleware/logging/statsd_spec.rb
|
97
98
|
- spec/middleware/request/retry_spec.rb
|
99
|
+
- spec/middleware/response/default_response_spec.rb
|
98
100
|
- spec/multiple_spec.rb
|
99
101
|
- spec/requester/get_spec.rb
|
100
102
|
- spec/requester/post_spec.rb
|
@@ -130,6 +132,7 @@ test_files:
|
|
130
132
|
- spec/middleware/logging/rails_spec.rb
|
131
133
|
- spec/middleware/logging/statsd_spec.rb
|
132
134
|
- spec/middleware/request/retry_spec.rb
|
135
|
+
- spec/middleware/response/default_response_spec.rb
|
133
136
|
- spec/multiple_spec.rb
|
134
137
|
- spec/requester/get_spec.rb
|
135
138
|
- spec/requester/post_spec.rb
|