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 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
- end
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
- unless @ignored_exceptions.include?(e.class)
26
- # Retry a limited number of times
27
- if retries > 0
28
- retries -= 1
29
- sleep(backoff) if backoff > 0.0
30
- backoff *= 2
31
- retry
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
@@ -12,7 +12,7 @@ module Saddle
12
12
  def call(env)
13
13
  begin
14
14
  @app.call(env)
15
- rescue Faraday::Error
15
+ rescue Faraday::Error::ClientError
16
16
  if res = env[:request][:default_response]
17
17
  return ::Faraday::Response.new(:body => res)
18
18
  else
@@ -13,7 +13,7 @@ module Saddle
13
13
  class RubyTimeout < Faraday::Middleware
14
14
 
15
15
  def call(env)
16
- timeout = env[:request][:timeout] # nil or 0 means no timeout
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
@@ -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
- # Set up a user agent (named for the client's namespace)
127
- builder.headers[:user_agent] = @parent_client.root_namespace
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
 
@@ -1,3 +1,3 @@
1
1
  module Saddle
2
- VERSION = '0.0.27'
2
+ VERSION = '0.0.30'
3
3
  end
@@ -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
- it "should retry properly with no params" do
16
- @stubs.get('/test') {
17
- [
18
- 500,
19
- {},
20
- 'Failure',
21
- ]
22
- }
23
- @stubs.get('/test') {
24
- [
25
- 200,
26
- {},
27
- 'Party!',
28
- ]
29
- }
30
- @default_client.requester.get('/test').should == 'Party!'
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
- it "should retry properly when posting params urlencoded" do
34
- @stubs.post('/test', '{"a":"b","c":"d"}') {
35
- [
36
- 500,
37
- {},
38
- 'Failure',
39
- ]
40
- }
41
- @stubs.post('/test', '{"a":"b","c":"d"}') {
42
- [
43
- 200,
44
- {},
45
- 'Party!',
46
- ]
47
- }
48
- @default_client.requester.post(
49
- '/test',
50
- {'a' => 'b', 'c' => 'd'}
51
- ).should == 'Party!'
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.27
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