px-service-client 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e1b9f1c89d04e85c5a9651110610cd09db6ef51
4
- data.tar.gz: c7c29ca34280c62c4bdfb5f509975d2f805b9a1b
3
+ metadata.gz: db46c3146668dad3c40c3a5cabc1feaf4743b745
4
+ data.tar.gz: 94824bed638685d41404aee9739453fdc2f79280
5
5
  SHA512:
6
- metadata.gz: bb8754feff57a33821f4f7fb1fe0e3f0e918f127fd339874a7e3e74ed4b1213827764a4b4cc4bc10dad400db052f86094a2898e2e97733de526cb92ab3229dc0
7
- data.tar.gz: 6306f318dc756f99d0bcd5a553e2ec77a58fc8bb1afa150aecd246ca355246c6332b3d46673486a2f7759fafc903149b3e85861b996335f281067f6e63367d78
6
+ metadata.gz: 232d9cee11917707c1463cc1d53a9b1336225ef4cb22d5611a3dce074eb6b2feb9ca7e3b5420b69018f0d4acfa847407b37426519482ffd501df2c66875a1a59
7
+ data.tar.gz: 1d1b736be0ebc4a91957c09832a34ae892e16690d4f4df9dca211496bc6deb5c3d2f8f46e534999373b0ea51821453ce08cac9dd64a9c0e8bec64b8c2a85f340
data/README.md CHANGED
@@ -38,7 +38,7 @@ This gem includes several common features used in 500px service client libraries
38
38
  The features are:
39
39
 
40
40
  #### Px::Service::Client::Base
41
- This class provides a basic `make_request(method, url, ...)` method that produces an asynchronous request. The method immediately returns a `RetriableResponseFuture`. It works together with `Multiplexer`(discussed below) and uses [Typhoeus](https://github.com/typhoeus/typhoeus) as the underlying HTTP client to support asynchronicity.
41
+ This class provides a basic `make_request(method, url, ...)` method that produces an asynchronous request. The method immediately returns a `Future`. It works together with `Multiplexer`(discussed below) and uses [Typhoeus](https://github.com/typhoeus/typhoeus) as the underlying HTTP client to support asynchronicity.
42
42
 
43
43
  **Customized clients usually inherit this class and include other features/mixins, if needed.**
44
44
 
@@ -55,7 +55,7 @@ multi = Px::Service::Client::Multiplexer.new
55
55
  multi.context do
56
56
  method = :get
57
57
  url = 'http://www.example.com'
58
- req = make_request(method, url) # returns a RetriableResponseFuture
58
+ req = make_request(method, url) # returns a Future
59
59
  multi.do(req) # queues the request/future into hydra
60
60
  end
61
61
 
@@ -64,9 +64,9 @@ multi.run # a blocking call, like hydra.run
64
64
  ```
65
65
  `multi.context` encapsulates the block into a [`Fiber`](http://ruby-doc.org/core-2.2.0/Fiber.html) object and immediately runs (or `resume`, in Fiber's term) that fiber until the block explicitly gives up control. The method returns `multi` itself.
66
66
 
67
- `multi.do(request_or_future,retries)` queues the request into `hydra`. It always returns a `RetriableResponseFuture`. A [`Typhoeus::Request`](https://github.com/typhoeus/typhoeus) will be converted into a `RetriableResponseFuture ` in this call.
67
+ `multi.do(request_or_future,retries)` queues the request into `hydra`. It always returns a `Future`. A [`Typhoeus::Request`](https://github.com/typhoeus/typhoeus) will be converted into a `Future ` in this call.
68
68
 
69
- Finally, `multi.run` starts `hydra` to execute the requests in parallel. The request is made as soon as the multiplexer is started. You get the results of the request by evaluating the value of the `RetriableResponseFuture`.
69
+ Finally, `multi.run` starts `hydra` to execute the requests in parallel. The request is made as soon as the multiplexer is started. You get the results of the request by evaluating the value of the `Future`.
70
70
 
71
71
  #### Px::Service::Client::Caching
72
72
 
@@ -89,12 +89,29 @@ end
89
89
  # An example of a cached request
90
90
  result = cache_request(url, :last_resort, refresh_probability: 1) do
91
91
  req = make_request(method, url)
92
+ response = @multi.do(req)
93
+
94
+ # cache_request() expects a future that returns the result to be cached
95
+ Px::Service::Client::Future.new do
96
+ JSON.parse(response.body)
97
+ end
92
98
  end
93
99
  ```
94
100
 
95
- `cache_request` expects a block that does the `make_request` and returns a `RetriableResponseFuture`. The block takes no argument. If neither the cache nor the response has the data, the exception `ServiceError` will be re-raised.
101
+ `cache_request` expects a block that returns a `Future` object. The return value (usually the response body) of that future will be cached. `cache_request` always returns a future. By evaluating the future, i.e., via the `Future.value!` call, you get the result (whether cached or not).
102
+
103
+
104
+ **Note**: DO NOT cache the `Typhoeus::Response` directly (See the below code snippet), because the response object cannot be serializable to be stored in memcached. That's the reason why we see warning message: `You are trying to cache a Ruby object which cannot be serialized to memcached.`
105
+
106
+ ```
107
+ # An incorrect example of using cache_request()
108
+ cache_request(url, :last_resort) do
109
+ req = make_request(method, url)
110
+ response = @multi.do(req) # DO NOT do this
111
+ end
96
112
 
97
- Responses are cached in memcached (using the provided cache client) in either a *last-resort* or *first-resort* manner.
113
+ ```
114
+ Responses are cached in either a *last-resort* or *first-resort* manner.
98
115
 
99
116
  *last-resort* means that the cached value is only used when the service client request fails (with a
100
117
  `ServiceError`). If the service client request succeeds, there is a chance that the cache value may get refreshed. The `refresh_probability` is provided to let the cached value
@@ -125,7 +142,7 @@ end
125
142
  req = make_request(method, url) # overrides Px::Service::Client::Base
126
143
  ```
127
144
 
128
- Adds a circuit breaker to the client. `make_request` always returns `RetriableResponseFuture`
145
+ Adds a circuit breaker to the client. `make_request` always returns `Future`
129
146
 
130
147
  The circuit will open on any exception from the wrapped method, or if the request runs for longer than the `invocation_timeout`.
131
148
 
@@ -72,8 +72,7 @@ module Px::Service::Client
72
72
  begin
73
73
  raise ArgumentError.new('Block did not return a Future.') unless retry_response.is_a?(Future)
74
74
  resp = retry_response.value!
75
-
76
- entry = CacheEntry.new(config.cache_client, url, policy_group, resp.options)
75
+ entry = CacheEntry.new(config.cache_client, url, policy_group, resp)
77
76
 
78
77
  # Only store a new result if we roll a 0
79
78
  r = rand(refresh_probability)
@@ -88,7 +87,7 @@ module Px::Service::Client
88
87
  end
89
88
 
90
89
  entry.touch(expires_in, refresh_window: 1.minute)
91
- Typhoeus::Response.new(HashWithIndifferentAccess.new(entry.data))
90
+ entry.data
92
91
  end
93
92
  end
94
93
  end
@@ -109,7 +108,7 @@ module Px::Service::Client
109
108
  # don't also try to update the cache.
110
109
  entry.touch(expires_in)
111
110
  else
112
- return Future.new { Typhoeus::Response.new(HashWithIndifferentAccess.new(entry.data)) }
111
+ return Future.new { entry.data }
113
112
  end
114
113
  end
115
114
 
@@ -119,8 +118,7 @@ module Px::Service::Client
119
118
  begin
120
119
  raise ArgumentError.new('Block did not return a Future.') unless retry_response.is_a?(Future)
121
120
  resp = retry_response.value!
122
-
123
- entry = CacheEntry.new(config.cache_client, url, policy_group, resp.options)
121
+ entry = CacheEntry.new(config.cache_client, url, policy_group, resp)
124
122
  entry.store(expires_in)
125
123
  resp
126
124
  rescue Px::Service::ServiceError => ex
@@ -135,7 +133,7 @@ module Px::Service::Client
135
133
  # Set the entry to be expired again (but reset the refresh window). This allows the next call to try again
136
134
  # (assuming the circuit breaker is reset) but keeps the value in the cache in the meantime
137
135
  entry.touch(0.seconds)
138
- Typhoeus::Response.new(HashWithIndifferentAccess.new(entry.data))
136
+ entry.data
139
137
  end
140
138
  end
141
139
 
@@ -1,7 +1,7 @@
1
1
  module Px
2
2
  module Service
3
3
  module Client
4
- VERSION = "1.2.2"
4
+ VERSION = "1.2.3"
5
5
  end
6
6
  end
7
7
  end
@@ -67,8 +67,8 @@ describe Px::Service::Client::Base do
67
67
  Typhoeus.stub(url).and_return(response)
68
68
  end
69
69
 
70
- shared_examples_for 'a request that returns a cached response' do
71
- let(:cache_entry) { Px::Service::Client::Caching::CacheEntry.new(dalli, url, 'general', future, Time.now + 1.year) }
70
+ shared_examples_for 'a request that returns a cached response body' do
71
+ let(:cache_entry) { Px::Service::Client::Caching::CacheEntry.new(dalli, url, 'general', response.body, Time.now + 1.year) }
72
72
 
73
73
  before :each do
74
74
  Typhoeus::Expectation.clear
@@ -80,8 +80,10 @@ describe Px::Service::Client::Base do
80
80
  multi.context do
81
81
  resp = multi.do(req)
82
82
  end.run
83
-
84
- resp
83
+
84
+ Px::Service::Client::Future.new do
85
+ resp.options[:body]
86
+ end
85
87
  end
86
88
  end
87
89
 
@@ -94,12 +96,14 @@ describe Px::Service::Client::Base do
94
96
  multi.context do
95
97
  resp = multi.do(req)
96
98
  end.run
97
-
98
- resp
99
+
100
+ Px::Service::Client::Future.new do
101
+ resp.options[:body]
102
+ end
99
103
  end
100
104
  end
101
105
 
102
- it 'returns the cached response' do
106
+ it 'returns the cached response body' do
103
107
  Typhoeus::Expectation.clear
104
108
  Typhoeus.stub(url).and_return(response)
105
109
  req = subject.send(:make_request, 'get', url)
@@ -108,10 +112,12 @@ describe Px::Service::Client::Base do
108
112
 
109
113
  multi.context do
110
114
  resp = multi.do(req)
111
- expect(resp).to eq(cache_entry.data)
112
- end.run
115
+ expect(resp.options[:body]).to eq(cache_entry.data)
116
+ end
113
117
 
114
- resp
118
+ Px::Service::Client::Future.new do
119
+ resp.options[:body]
120
+ end
115
121
  end
116
122
  end
117
123
  end
@@ -120,7 +126,7 @@ describe Px::Service::Client::Base do
120
126
  let(:strategy) { :first_resort }
121
127
  let(:response) { successful_response }
122
128
 
123
- it_behaves_like 'a request that returns a cached response'
129
+ it_behaves_like 'a request that returns a cached response body'
124
130
 
125
131
  context 'when the request fails' do
126
132
  let(:response) do
@@ -141,8 +147,10 @@ describe Px::Service::Client::Base do
141
147
  resp = multi.do(req)
142
148
  called = true
143
149
  end.run
144
-
145
- resp
150
+
151
+ Px::Service::Client::Future.new do
152
+ resp.options[:body]
153
+ end
146
154
  end
147
155
 
148
156
  expect(called).to be_truthy
@@ -156,15 +164,17 @@ describe Px::Service::Client::Base do
156
164
  multi.context do
157
165
  resp = multi.do(req)
158
166
  end.run
159
-
160
- resp
167
+
168
+ Px::Service::Client::Future.new do
169
+ resp.options[:body]
170
+ end
161
171
  end.value!
162
172
  }.to raise_error(Px::Service::ServiceError, 'Failed')
163
173
  end
164
174
  end
165
175
 
166
176
  context 'when a response has been cached' do
167
- it_behaves_like 'a request that returns a cached response'
177
+ it_behaves_like 'a request that returns a cached response body'
168
178
  end
169
179
  end
170
180
  end
@@ -183,8 +193,10 @@ describe Px::Service::Client::Base do
183
193
  resp = multi.do(req)
184
194
  called = true
185
195
  end.run
186
-
187
- resp
196
+
197
+ Px::Service::Client::Future.new do
198
+ resp.options[:body]
199
+ end
188
200
  end
189
201
 
190
202
  expect(called).to be_truthy
@@ -203,14 +215,16 @@ describe Px::Service::Client::Base do
203
215
  called = false
204
216
  req = subject.send(:make_request, 'get', url)
205
217
 
206
- subject.cache_request(req.request.url, strategy: strategy) do
218
+ subject.cache_request(req.request.url, strategy: strategy, refresh_probability: 0) do
207
219
  resp = nil
208
220
  multi.context do
209
221
  resp = multi.do(req)
210
222
  called = true
211
223
  end.run
212
-
213
- resp
224
+
225
+ Px::Service::Client::Future.new do
226
+ resp.options[:body]
227
+ end
214
228
  end
215
229
 
216
230
  expect(called).to be_truthy
@@ -225,14 +239,16 @@ describe Px::Service::Client::Base do
225
239
  multi.context do
226
240
  resp = multi.do(req)
227
241
  end.run
228
-
229
- resp
242
+
243
+ Px::Service::Client::Future.new do
244
+ resp.options[:body]
245
+ end
230
246
  end.value!
231
247
  }.to raise_error(Px::Service::ServiceError, 'Failed')
232
248
  end
233
249
  end
234
250
 
235
- context 'when a response has been cached' do
251
+ context 'when a response body has been cached' do
236
252
  before :each do
237
253
  Typhoeus::Expectation.clear
238
254
  Typhoeus.stub(url).and_return(successful_response)
@@ -245,7 +261,9 @@ describe Px::Service::Client::Base do
245
261
  resp = multi.do(req)
246
262
  end.run
247
263
 
248
- resp
264
+ Px::Service::Client::Future.new do
265
+ resp.options[:body]
266
+ end
249
267
  end
250
268
  end
251
269
 
@@ -259,13 +277,15 @@ describe Px::Service::Client::Base do
259
277
  called = true
260
278
  end.run
261
279
 
262
- resp
280
+ Px::Service::Client::Future.new do
281
+ resp.options[:body]
282
+ end
263
283
  end
264
284
 
265
285
  expect(called).to be_truthy
266
286
  end
267
287
 
268
- it 'returns the cached response' do
288
+ it 'returns the cached response body' do
269
289
  Typhoeus::Expectation.clear
270
290
  Typhoeus.stub(url).and_return(response)
271
291
  req = subject.send(:make_request, 'get', url)
@@ -275,9 +295,11 @@ describe Px::Service::Client::Base do
275
295
  multi.context do
276
296
  resp = multi.do(req)
277
297
  end.run
278
-
279
- resp
280
- end.value!.response_code).to be(200)
298
+
299
+ Px::Service::Client::Future.new do
300
+ resp.options[:body]
301
+ end
302
+ end.value!['status']).to be(200)
281
303
  end
282
304
  end
283
305
 
@@ -39,7 +39,7 @@ describe Px::Service::Client::Caching do
39
39
  it "should call the block" do
40
40
  called = false
41
41
  subject.cache_request(url, strategy: strategy) do
42
- called = true
42
+ Px::Service::Client::Future.new { called = true }
43
43
  end
44
44
 
45
45
  expect(called).to be_truthy
@@ -131,7 +131,7 @@ describe Px::Service::Client::Caching do
131
131
  it "returns the cached response on failure" do
132
132
  expect(subject.cache_request(url, strategy: strategy) do
133
133
  Px::Service::Client::Future.new { raise Px::Service::ServiceError.new("Error", 500) }
134
- end.value!.options).to eq(response.options.stringify_keys)
134
+ end.value!).to eq(response.options)
135
135
  end
136
136
 
137
137
  it "does not returns the cached response on request error" do
@@ -195,8 +195,10 @@ describe Px::Service::Client::Caching do
195
195
 
196
196
  it "returns the response" do
197
197
  expect(subject.cache_request(url, strategy: strategy) do
198
- nil
199
- end.value!.options).to eq(response.options.stringify_keys)
198
+ Future.new do
199
+ nil
200
+ end
201
+ end.value!).to eq(response.options)
200
202
  end
201
203
  end
202
204
  end
@@ -217,7 +219,10 @@ describe Px::Service::Client::Caching do
217
219
  it "invokes the block" do
218
220
  called = false
219
221
  subject.cache_request(url, strategy: strategy) do |u|
220
- called = true
222
+ Px::Service::Client::Future.new do
223
+ called = true
224
+ { stub: "stub str" }.to_hash
225
+ end
221
226
  end
222
227
 
223
228
  expect(called).to be_truthy
@@ -252,7 +257,7 @@ describe Px::Service::Client::Caching do
252
257
  end.run
253
258
 
254
259
  resp
255
- end.value!.options).to eq(response.options.stringify_keys)
260
+ end.value!).to eq(response.options)
256
261
 
257
262
  expect(called).to be_falsey
258
263
 
@@ -272,13 +277,13 @@ describe Px::Service::Client::Caching do
272
277
 
273
278
  expect(subject.cache_request(url, strategy: strategy) do
274
279
  nil
275
- end.value.options).to eq(response.options.stringify_keys)
280
+ end.value).to eq(response.options)
276
281
  end
277
282
 
278
283
  it "returns the cached response on failure" do
279
284
  expect(subject.cache_request(url, strategy: strategy) do
280
285
  Px::Service::Client::Future.new { raise Px::Service::ServiceError.new("Error", 500) }
281
- end.value!.options).to eq(response.options.stringify_keys)
286
+ end.value!).to eq(response.options)
282
287
  end
283
288
 
284
289
  it "does not returns the cached response on request error" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: px-service-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Micacchi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-19 00:00:00.000000000 Z
11
+ date: 2016-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: will_paginate