px-service-client 1.0.6 → 1.1.0

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