saddle 0.0.27 → 0.0.30

Sign up to get free protection for your applications and to get access to all the features.
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