px-service-client 1.0.6 → 1.1.0

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: c456bfefca448cba29a988f43b0170d6f15c74e8
4
- data.tar.gz: 3c8e4664102e71baa40f5be677b6e9e41e1187d4
3
+ metadata.gz: eed1491471134440a4e1ca1644420395f15079e4
4
+ data.tar.gz: 5f50c16950abc5f20cd7eb7d82deb75f5731782e
5
5
  SHA512:
6
- metadata.gz: 1a96bb88370ad38d33533d624acb004f81826f66529f20e744eedb50849aaf7560c1ca2cd3d3f421fc826521bfebec12f02c952056731ac8ab90785cd90108d4
7
- data.tar.gz: 1a2a252723fb795709c37c19b57076eafccc7571f27e056b1b73351ad33c9b3a8bb0a6a162ef28e0d423b4d91acabc593b6ef9cbd7894707d7dd15100f3c1f2f
6
+ metadata.gz: cd65c7907b1870c02add4c35a4360df9487b8974b92b9bdfc2a0af941b6f1a2e44870b8b8c409d7235c72a103bc0d64d8828038bcc54457b2949c014b02f2051
7
+ data.tar.gz: cf39f661fb5c27d1643b036afd7d3b28028e9dc098186775dbb461a852bd9ae3b201b629685eb364e2e6ae5b768d29c3b1edb0a35f8952123e2fb784bbfd8c02
@@ -1,6 +1,5 @@
1
1
  module Px::Service::Client
2
2
  class Base
3
- include Px::Service::Client::Caching
4
3
  cattr_accessor :logger
5
4
 
6
5
  private
@@ -23,8 +23,9 @@ module Px::Service::Client::Caching
23
23
  ActiveSupport::Notifications.instrument("store.caching", { url: url, policy_group: policy_group, expires_in: expires_in} ) do
24
24
  real_expiry = real_cache_expiry(expires_in, refresh_window: refresh_window)
25
25
  cache_client.multi do
26
- cache_client.set(cache_key(:data), data.to_json, real_expiry)
27
- cache_client.set(cache_key(:meta), metadata.to_json, real_expiry)
26
+ data_json = data.is_a?(Hash) ? data.to_json : data
27
+ cache_client.set(cache_key(:data), data_json, real_expiry)
28
+ cache_client.set(cache_key(:meta), metadata, real_expiry)
28
29
  end
29
30
  end
30
31
  end
@@ -59,7 +60,7 @@ module Px::Service::Client::Caching
59
60
  real_expiry = real_cache_expiry(expires_in, refresh_window: refresh_window)
60
61
 
61
62
  cache_client.touch(cache_key(:data), real_expiry)
62
- cache_client.set(cache_key(:meta), metadata.to_json, real_expiry)
63
+ cache_client.set(cache_key(:meta), metadata, real_expiry)
63
64
  end
64
65
  end
65
66
 
@@ -70,7 +71,7 @@ module Px::Service::Client::Caching
70
71
  "url" => url,
71
72
  "pg" => policy_group,
72
73
  "expires_at" => expires_at,
73
- }
74
+ }.to_json
74
75
  end
75
76
 
76
77
  def cache_key(type)
@@ -20,14 +20,41 @@ module Px::Service::Client
20
20
  cattr_accessor :cache_client, :cache_logger
21
21
  end
22
22
 
23
- def cache_request(url, strategy: :last_resort, expires_in: 30.seconds, **options, &block)
23
+ module ClassMethods
24
+ DefaultConfig = Struct.new(:cache_strategy, :cache_expiry, :max_page, :cache_options, :cache_client) do
25
+ def initialize
26
+ self.cache_strategy = :none
27
+ self.cache_expiry = 30.seconds
28
+ self.max_page = nil
29
+ self.cache_options = {}
30
+ self.cache_options[:policy_group] = 'general'
31
+ self.cache_client = nil
32
+ end
33
+ end
34
+
35
+ ##
36
+ # Set the caching behaviour
37
+ def caching(&block)
38
+ @cache_config ||= DefaultConfig.new
39
+ yield(@cache_config) if block_given?
40
+ @cache_config
41
+ end
42
+ end
43
+
44
+ def config
45
+ @cache_config || self.class.caching
46
+ end
47
+
48
+ def cache_request(url, strategy: nil, **options, &block)
49
+ strategy ||= config.cache_strategy
50
+
24
51
  case strategy
25
52
  when :first_resort
26
- cache_first_resort(url, expires_in: expires_in, **options, &block)
53
+ cache_first_resort(url, policy_group: config.cache_options[:policy_group], expires_in: config.cache_expiry, **options, &block)
27
54
  when :last_resort
28
- cache_last_resort(url, expires_in: expires_in, **options, &block)
55
+ cache_last_resort(url, policy_group: config.cache_options[:policy_group], expires_in: config.cache_expiry, **options, &block)
29
56
  else
30
- no_cache(url, &block)
57
+ no_cache(&block)
31
58
  end
32
59
  end
33
60
 
@@ -40,27 +67,34 @@ module Px::Service::Client
40
67
  def cache_last_resort(url, policy_group: 'general', expires_in: nil, refresh_probability: 1, &block)
41
68
  # Note we use a smaller refresh window here (technically, could even use 0)
42
69
  # since we don't really need the "expired but not really expired" behaviour when caching as a last resort.
43
- begin
44
- response = block.call(url)
45
-
46
- entry = CacheEntry.new(cache_client, url, policy_group, response)
47
-
48
- # Only store a new result if we roll a 0
49
- r = rand(refresh_probability)
50
- entry.store(expires_in, refresh_window: 1.minute) if r == 0
51
-
52
- response
53
- rescue Px::Service::ServiceError => ex
54
- cache_logger.error "Service responded with exception: #{ex.class.name}: #{ex.message}\n#{ex.backtrace.join('\n')}" if cache_logger
55
-
56
- entry = CacheEntry.fetch(cache_client, url, policy_group)
57
- if entry.nil?
58
- # Re-raise the error, no cached response
59
- raise ex
70
+ retry_response = block.call
71
+
72
+ Future.new do
73
+ begin
74
+ if retry_response.is_a?(Future)
75
+ resp = retry_response.value!.options
76
+ else
77
+ resp = retry_response
78
+ end
79
+
80
+ entry = CacheEntry.new(config.cache_client, url, policy_group, resp)
81
+
82
+ # Only store a new result if we roll a 0
83
+ r = rand(refresh_probability)
84
+ entry.store(expires_in, refresh_window: 1.minute) if r == 0
85
+ resp
86
+ rescue Px::Service::ServiceError => ex
87
+ cache_logger.error "Service responded with exception: #{ex.class.name}: #{ex.message}\n#{ex.backtrace.join('\n')}" if cache_logger
88
+
89
+ entry = CacheEntry.fetch(config.cache_client, url, policy_group)
90
+ if entry.nil?
91
+ # Re-raise the error, no cached response
92
+ raise ex
93
+ end
94
+
95
+ entry.touch(expires_in, refresh_window: 1.minute)
96
+ entry.data
60
97
  end
61
-
62
- entry.touch(expires_in, refresh_window: 1.minute)
63
- entry.data
64
98
  end
65
99
  end
66
100
 
@@ -70,7 +104,7 @@ module Px::Service::Client
70
104
  # has expired (but is still present) and the request fails, the cached value is still returned, as if this was
71
105
  # cache_last_resort.
72
106
  def cache_first_resort(url, policy_group: 'general', expires_in: nil, &block)
73
- entry = CacheEntry.fetch(cache_client, url, policy_group)
107
+ entry = CacheEntry.fetch(config.cache_client, url, policy_group)
74
108
 
75
109
  if entry
76
110
  if entry.expired?
@@ -80,33 +114,52 @@ module Px::Service::Client
80
114
  # don't also try to update the cache.
81
115
  entry.touch(expires_in)
82
116
  else
83
- return entry.data
117
+ return Future.new { entry.data }
84
118
  end
85
119
  end
86
120
 
87
- begin
88
- response = block.call(url)
121
+ retry_response = block.call
122
+
123
+ Future.new do
124
+ begin
125
+ if retry_response.is_a?(Future)
126
+ resp = retry_response.value!.options
127
+ else
128
+ resp = retry_response
129
+ end
130
+
131
+ entry = CacheEntry.new(config.cache_client, url, policy_group, resp)
132
+ entry.store(expires_in)
133
+ resp
134
+ rescue Px::Service::ServiceError => ex
135
+ cache_logger.error "Service responded with exception: #{ex.class.name}: #{ex.message}\n#{ex.backtrace.join('\n')}" if cache_logger
136
+
137
+ entry = CacheEntry.fetch(config.cache_client, url, policy_group)
138
+ if entry.nil?
139
+ # Re-raise the error, no cached response
140
+ raise ex
141
+ end
142
+
143
+ # Set the entry to be expired again (but reset the refresh window). This allows the next call to try again
144
+ # (assuming the circuit breaker is reset) but keeps the value in the cache in the meantime
145
+ entry.touch(0.seconds)
146
+ entry.data
147
+ end
148
+ end
149
+ end
89
150
 
90
- entry = CacheEntry.new(cache_client, url, policy_group, response)
91
- entry.store(expires_in)
92
- response
93
- rescue Px::Service::ServiceError => ex
94
- cache_logger.error "Service responded with exception: #{ex.class.name}: #{ex.message}\n#{ex.backtrace.join('\n')}" if cache_logger
151
+ def no_cache(&block)
152
+ retry_response = block.call
95
153
 
96
- if entry.nil?
97
- # Re-raise the error, no cached response
98
- raise ex
154
+ Future.new do
155
+ if retry_response.is_a?(Future)
156
+ resp = retry_response.value!.options
157
+ else
158
+ resp = retry_response
99
159
  end
100
160
 
101
- # Set the entry to be expired again (but reset the refresh window). This allows the next call to try again
102
- # (assuming the circuit breaker is reset) but keeps the value in the cache in the meantime
103
- entry.touch(0.seconds)
104
- entry.data
161
+ resp
105
162
  end
106
163
  end
107
-
108
- def no_cache(url, &block)
109
- block.call(url)
110
- end
111
164
  end
112
165
  end
@@ -17,7 +17,9 @@ module Px::Service::Client
17
17
  def do(request_or_future, retries: RetriableResponseFuture::DEFAULT_RETRIES)
18
18
  response = request_or_future
19
19
  if request_or_future.is_a?(Typhoeus::Request)
20
- response = RetriableResponseFuture(request_or_future, retries: retries)
20
+ response = RetriableResponseFuture.new(request_or_future, retries: retries)
21
+ elsif !request_or_future.is_a?(RetriableResponseFuture)
22
+ return request_or_future
21
23
  end
22
24
 
23
25
  # Will automatically queue the request on the hydra
@@ -1,7 +1,7 @@
1
1
  module Px
2
2
  module Service
3
3
  module Client
4
- VERSION = "1.0.6"
4
+ VERSION = "1.1.0"
5
5
  end
6
6
  end
7
7
  end
@@ -1,8 +1,19 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Px::Service::Client::Base do
4
- subject { Px::Service::Client::Base.send(:new) }
5
- let(:response) do
4
+ let(:dalli_host) { ENV['PX_MEMCACHED_HOST'] }
5
+ let(:dalli_options) { { :namespace => "service-client-test", expires_in: 3600, compress: false, failover: false } }
6
+ let(:dalli) { Dalli::Client.new(dalli_host, dalli_options) }
7
+
8
+ subject {
9
+ Px::Service::Client::Base.include(Px::Service::Client::Caching).tap do |c|
10
+ c.caching do |config|
11
+ config.cache_client = dalli
12
+ end
13
+ end.new
14
+ }
15
+
16
+ let(:successful_response) do
6
17
  Typhoeus::Response.new(
7
18
  code: 200,
8
19
  body: { status: 200, message: "Success"}.to_json,
@@ -45,5 +56,234 @@ describe Px::Service::Client::Base do
45
56
  expect(resp.request.url).to include("one=a&two=b")
46
57
  end
47
58
  end
59
+
60
+ context "when the caching strategy is set" do
61
+ let(:multi) { Px::Service::Client::Multiplexer.new }
62
+ let(:request) { Typhoeus::Request.new(url, method: :get) }
63
+ let(:future) { Px::Service::Client::RetriableResponseFuture.new(request) }
64
+
65
+ before :each do
66
+ dalli.flush_all
67
+ Typhoeus.stub(url).and_return(response)
68
+ end
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) }
72
+
73
+ before :each do
74
+ Typhoeus::Expectation.clear
75
+ Typhoeus.stub(url).and_return(successful_response)
76
+
77
+ req = subject.send(:make_request, 'get', url)
78
+ subject.cache_request(req.request.url, strategy: strategy) do
79
+ resp = nil
80
+ multi.context do
81
+ resp = multi.do(req)
82
+ end.run
83
+
84
+ resp
85
+ end
86
+ end
87
+
88
+ it 'does not return a new response' do
89
+ req = subject.send(:make_request, 'get', url)
90
+
91
+ expect(Px::Service::Client::RetriableResponseFuture).to_not receive(:new)
92
+ subject.cache_request(req.request.url, strategy: strategy) do
93
+ resp = nil
94
+ multi.context do
95
+ resp = multi.do(req)
96
+ end.run
97
+
98
+ resp
99
+ end
100
+ end
101
+
102
+ it 'returns the cached response' do
103
+ Typhoeus::Expectation.clear
104
+ Typhoeus.stub(url).and_return(response)
105
+ req = subject.send(:make_request, 'get', url)
106
+ subject.cache_request(req.request.url, strategy: strategy) do
107
+ resp = nil
108
+
109
+ multi.context do
110
+ resp = multi.do(req)
111
+ expect(resp).to eq(cache_entry.data)
112
+ end.run
113
+
114
+ resp
115
+ end
116
+ end
117
+ end
118
+
119
+ context 'to first_resort' do
120
+ let(:strategy) { :first_resort }
121
+ let(:response) { successful_response }
122
+
123
+ it_behaves_like 'a request that returns a cached response'
124
+
125
+ context 'when the request fails' do
126
+ let(:response) do
127
+ Typhoeus::Response.new(
128
+ code: 500,
129
+ body: { status: 500, error: "Failed"}.to_json,
130
+ headers: { "Content-Type" => "application/json"} )
131
+ end
132
+
133
+ context 'when no response is cached' do
134
+ it 'makes the request' do
135
+ called = false
136
+ req = subject.send(:make_request, 'get', url)
137
+
138
+ subject.cache_request(req.request.url, strategy: strategy) do
139
+ resp = nil
140
+ multi.context do
141
+ resp = multi.do(req)
142
+ called = true
143
+ end.run
144
+
145
+ resp
146
+ end
147
+
148
+ expect(called).to be_truthy
149
+ end
150
+
151
+ it 'returns an error' do
152
+ req = subject.send(:make_request, 'get', url)
153
+ expect {
154
+ subject.cache_request(req.request.url, strategy: strategy) do
155
+ resp = nil
156
+ multi.context do
157
+ resp = multi.do(req)
158
+ end.run
159
+
160
+ resp
161
+ end.value!
162
+ }.to raise_error(Px::Service::ServiceError, 'Failed')
163
+ end
164
+ end
165
+
166
+ context 'when a response has been cached' do
167
+ it_behaves_like 'a request that returns a cached response'
168
+ end
169
+ end
170
+ end
171
+
172
+ context 'to last_resort' do
173
+ let(:strategy) { :last_resort }
174
+ let(:response) { successful_response }
175
+
176
+ it 'makes the request' do
177
+ called = false
178
+ req = subject.send(:make_request, 'get', url)
179
+
180
+ subject.cache_request(req.request.url, strategy: strategy) do
181
+ resp = nil
182
+ multi.context do
183
+ resp = multi.do(req)
184
+ called = true
185
+ end.run
186
+
187
+ resp
188
+ end
189
+
190
+ expect(called).to be_truthy
191
+ end
192
+
193
+ context 'when the request fails' do
194
+ let(:response) do
195
+ Typhoeus::Response.new(
196
+ code: 500,
197
+ body: { status: 500, error: "Failed"}.to_json,
198
+ headers: { "Content-Type" => "application/json"} )
199
+ end
200
+
201
+ context 'when no response is cached' do
202
+ it 'makes the request' do
203
+ called = false
204
+ req = subject.send(:make_request, 'get', url)
205
+
206
+ subject.cache_request(req.request.url, strategy: strategy) do
207
+ resp = nil
208
+ multi.context do
209
+ resp = multi.do(req)
210
+ called = true
211
+ end.run
212
+
213
+ resp
214
+ end
215
+
216
+ expect(called).to be_truthy
217
+ end
218
+
219
+ it 'raises an error' do
220
+ req = subject.send(:make_request, 'get', url)
221
+
222
+ expect {
223
+ subject.cache_request(req.request.url, strategy: strategy) do
224
+ resp = nil
225
+ multi.context do
226
+ resp = multi.do(req)
227
+ end.run
228
+
229
+ resp
230
+ end.value!
231
+ }.to raise_error(Px::Service::ServiceError, 'Failed')
232
+ end
233
+ end
234
+
235
+ context 'when a response has been cached' do
236
+ before :each do
237
+ Typhoeus::Expectation.clear
238
+ Typhoeus.stub(url).and_return(successful_response)
239
+
240
+ req = subject.send(:make_request, 'get', url)
241
+
242
+ subject.cache_request(req.request.url, strategy: strategy) do
243
+ resp = nil
244
+ multi.context do
245
+ resp = multi.do(req)
246
+ end.run
247
+
248
+ resp
249
+ end
250
+ end
251
+
252
+ it 'makes the request' do
253
+ called = false
254
+ req = subject.send(:make_request, 'get', url)
255
+ subject.cache_request(req.request.url, strategy: strategy) do
256
+ resp = nil
257
+ multi.context do
258
+ resp = multi.do(req)
259
+ called = true
260
+ end.run
261
+
262
+ resp
263
+ end
264
+
265
+ expect(called).to be_truthy
266
+ end
267
+
268
+ it 'returns the cached response' do
269
+ Typhoeus::Expectation.clear
270
+ Typhoeus.stub(url).and_return(response)
271
+ req = subject.send(:make_request, 'get', url)
272
+
273
+ expect(subject.cache_request(req.request.url, strategy: strategy) do
274
+ resp = nil
275
+ multi.context do
276
+ resp = multi.do(req)
277
+ end.run
278
+
279
+ resp
280
+ end.value!['code']).to eq(200)
281
+ end
282
+ end
283
+
284
+ end
285
+ end
286
+ end
48
287
  end
49
288
  end
289
+
@@ -2,32 +2,34 @@ require 'spec_helper'
2
2
  require 'dalli'
3
3
 
4
4
  describe Px::Service::Client::Caching do
5
+ let(:dalli_host) { ENV['PX_MEMCACHED_HOST'] }
6
+ let(:dalli_options) { { :namespace => "service-client-test", expires_in: 3600, compress: false, failover: false } }
7
+ let(:dalli) { Dalli::Client.new(dalli_host, dalli_options) }
8
+
5
9
  subject {
6
10
  Class.new.include(Px::Service::Client::Caching).tap do |c|
7
11
  # Anonymous classes don't have a name. Stub out :name so that things work
8
12
  allow(c).to receive(:name).and_return("Caching")
13
+
14
+ c.caching do |config|
15
+ config.cache_client = dalli
16
+ end
9
17
  end.new
10
18
  }
11
19
 
12
- let(:dalli_host) { "localhost:11211" }
13
- let(:dalli_options) { { :namespace => "service-client-test", expires_in: 3600, compress: false, failover: false } }
14
- let(:dalli) { Dalli::Client.new(dalli_host, dalli_options) }
20
+ let (:url) { "http://search/foo?bar=baz" }
21
+ let(:response) { { "response" => ["foo", "bar"], "status" => 200 } }
22
+ let(:entry) { Px::Service::Client::Caching::CacheEntry.new(dalli, url, 'general', response) }
23
+ let(:strategy) { :none }
15
24
 
16
25
  before :each do
17
26
  dalli.flush_all
18
- subject.cache_client = dalli
19
27
  end
20
28
 
21
- let (:url) { "http://search/foo?bar=baz"}
22
- let (:response) {
23
- { "response" => ["foo", "bar"], "status" => 200 }
24
- }
25
-
26
29
  shared_examples_for "a successful request" do
27
30
  it "should call the block" do
28
31
  called = false
29
- subject.cache_request(url, strategy: strategy) do |u|
30
- expect(u).to eq(url)
32
+ subject.cache_request(url, strategy: strategy) do
31
33
  called = true
32
34
  end
33
35
 
@@ -35,35 +37,35 @@ describe Px::Service::Client::Caching do
35
37
  end
36
38
 
37
39
  it "should return the block's return value" do
38
- expect(subject.cache_request(url, strategy: strategy) { response }).to eq(response)
40
+ expect(subject.cache_request(url, strategy: strategy) do
41
+ response
42
+ end.value!).to eq(response)
39
43
  end
40
44
  end
41
45
 
42
46
  shared_examples_for "a failed uncacheable request" do
43
47
  it "should raise the exception raised by the block" do
44
- expect{
48
+ expect {
45
49
  subject.cache_request(url, strategy: strategy) do
46
50
  # Px::Service::ServiceRequestError is not cachable
47
51
  # and does not trigger a fallback to a cached response
48
52
  raise Px::Service::ServiceRequestError.new("Error", 404)
49
- end
53
+ end.value!
50
54
  }.to raise_error(Px::Service::ServiceRequestError)
51
55
  end
52
56
  end
53
57
 
54
58
  shared_examples_for "a request with no cached response" do
55
59
  it "raises the exception" do
56
- expect {
60
+ expect {
57
61
  subject.cache_request(url, strategy: strategy) do
58
62
  raise Px::Service::ServiceError.new("Error", 500)
59
- end
63
+ end.value!
60
64
  }.to raise_error(Px::Service::ServiceError)
61
65
  end
62
66
  end
63
67
 
64
68
  context "when not caching" do
65
- let(:strategy) { :none }
66
-
67
69
  it_behaves_like "a successful request"
68
70
  it_behaves_like "a failed uncacheable request"
69
71
  end
@@ -76,22 +78,20 @@ describe Px::Service::Client::Caching do
76
78
 
77
79
  context "when there is a cached response" do
78
80
  before :each do
79
- subject.cache_request(url, strategy: strategy) do
80
- response
81
- end
81
+ Px::Service::Client::Caching::CacheEntry.stub(:fetch).and_return(entry)
82
82
  end
83
83
 
84
84
  it "returns the cached response on failure" do
85
85
  expect(subject.cache_request(url, strategy: strategy) do
86
- raise Px::Service::ServiceError.new("Error", 500)
87
- end).to eq(response)
86
+ Px::Service::Client::Future.new { raise Px::Service::ServiceError.new("Error", 500) }
87
+ end.value!).to eq(response)
88
88
  end
89
89
 
90
90
  it "does not returns the cached response on request error" do
91
91
  expect {
92
92
  subject.cache_request(url, strategy: strategy) do
93
- raise Px::Service::ServiceRequestError.new("Error", 404)
94
- end
93
+ Px::Service::Client::Future.new { raise Px::Service::ServiceRequestError.new("Error", 404) }
94
+ end.value!
95
95
  }.to raise_error(Px::Service::ServiceRequestError)
96
96
  end
97
97
 
@@ -99,7 +99,7 @@ describe Px::Service::Client::Caching do
99
99
  expect(dalli).to receive(:touch).with(a_kind_of(String), a_kind_of(Fixnum))
100
100
 
101
101
  subject.cache_request(url, strategy: strategy) do
102
- raise Px::Service::ServiceError.new("Error", 500)
102
+ Px::Service::Client::Future.new { raise Px::Service::ServiceError.new("Error", 500) }
103
103
  end
104
104
  end
105
105
  end
@@ -115,14 +115,13 @@ describe Px::Service::Client::Caching do
115
115
 
116
116
  context "when there is a cached response" do
117
117
  before :each do
118
- subject.cache_request(url, strategy: strategy) do
119
- response
120
- end
118
+ Px::Service::Client::Caching::CacheEntry.stub(:fetch).and_return(entry)
119
+ entry.expires_at = DateTime.now + 1.day
121
120
  end
122
121
 
123
122
  it "does not invoke the block" do
124
123
  called = false
125
- subject.cache_request(url, strategy: strategy) do |u|
124
+ subject.cache_request(url, strategy: strategy) do
126
125
  called = true
127
126
  end
128
127
 
@@ -130,17 +129,16 @@ describe Px::Service::Client::Caching do
130
129
  end
131
130
 
132
131
  it "returns the response" do
133
- expect(subject.cache_request(url, strategy: strategy) { nil }).to eq(response)
132
+ expect(subject.cache_request(url, strategy: strategy) do
133
+ nil
134
+ end.value!).to eq(response)
134
135
  end
135
136
  end
136
137
 
137
138
  context "when there is an expired cached response" do
138
139
  before :each do
139
- Timecop.freeze(10.minutes.ago) do
140
- subject.cache_request(url, strategy: strategy) do
141
- response
142
- end
143
- end
140
+ Px::Service::Client::Caching::CacheEntry.stub(:fetch).and_return(entry)
141
+ entry.expires_at = DateTime.now - 1.day
144
142
  end
145
143
 
146
144
  let (:response) { { "value" => "response" } }
@@ -155,7 +153,9 @@ describe Px::Service::Client::Caching do
155
153
  end
156
154
 
157
155
  it "returns the new response" do
158
- expect(subject.cache_request(url, strategy: strategy) { response }).to eq(response)
156
+ expect(subject.cache_request(url, strategy: strategy) do
157
+ response
158
+ end.value!).to eq(response)
159
159
  end
160
160
 
161
161
  it "updates the cache entry before making the request" do
@@ -166,7 +166,9 @@ describe Px::Service::Client::Caching do
166
166
  called = false
167
167
  expect(subject.cache_request(url, strategy: strategy) do
168
168
  called = true
169
- end).to eq(response)
169
+ response
170
+ end.value!).to eq(response)
171
+
170
172
  expect(called).to be_falsey
171
173
 
172
174
  response
@@ -178,20 +180,22 @@ describe Px::Service::Client::Caching do
178
180
  response
179
181
  end
180
182
 
181
- expect(subject.cache_request(url, strategy: strategy) { nil }).to eq(response)
183
+ expect(subject.cache_request(url, strategy: strategy) do
184
+ nil
185
+ end.value).to eq(response)
182
186
  end
183
187
 
184
188
  it "returns the cached response on failure" do
185
189
  expect(subject.cache_request(url, strategy: strategy) do
186
- raise Px::Service::ServiceError.new("Error", 500)
187
- end).to eq(response)
190
+ Px::Service::Client::Future.new { raise Px::Service::ServiceError.new("Error", 500) }
191
+ end.value!).to eq(response)
188
192
  end
189
193
 
190
194
  it "does not returns the cached response on request error" do
191
195
  expect {
192
196
  subject.cache_request(url, strategy: strategy) do
193
- raise Px::Service::ServiceRequestError.new("Error", 404)
194
- end
197
+ Px::Service::Client::Future.new { raise Px::Service::ServiceRequestError.new("Error", 404) }
198
+ end.value!
195
199
  }.to raise_error(Px::Service::ServiceRequestError)
196
200
  end
197
201
 
@@ -199,7 +203,7 @@ describe Px::Service::Client::Caching do
199
203
  expect(dalli).to receive(:touch).with(a_kind_of(String), a_kind_of(Fixnum)).twice
200
204
 
201
205
  subject.cache_request(url, strategy: strategy) do
202
- raise Px::Service::ServiceError.new("Error", 500)
206
+ Px::Service::Client::Future.new { raise Px::Service::ServiceError.new("Error", 500) }
203
207
  end
204
208
  end
205
209
  end
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.0.6
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Micacchi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-15 00:00:00.000000000 Z
11
+ date: 2016-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: will_paginate
@@ -283,7 +283,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
283
  version: '0'
284
284
  requirements: []
285
285
  rubyforge_project:
286
- rubygems_version: 2.2.1
286
+ rubygems_version: 2.4.6
287
287
  signing_key:
288
288
  specification_version: 4
289
289
  summary: Common service client behaviours for Ruby applications