px-service-client 1.2.2 → 1.2.3

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 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