right_support 2.10.1 → 2.11.2
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 +4 -4
- data/VERSION +1 -1
- data/lib/right_support/data/token.rb +51 -0
- data/lib/right_support/data.rb +1 -0
- data/lib/right_support/net/lb/base.rb +96 -0
- data/lib/right_support/net/lb/health_check.rb +22 -46
- data/lib/right_support/net/lb/round_robin.rb +5 -23
- data/lib/right_support/net/lb/sticky.rb +10 -27
- data/lib/right_support/net/lb.rb +2 -1
- data/lib/right_support/net/request_balancer.rb +184 -60
- data/lib/right_support/rack/request_logger.rb +221 -42
- data/lib/right_support/rack/request_tracker.rb +112 -25
- data/right_support.gemspec +11 -6
- data/spec/data/token_spec.rb +21 -0
- data/spec/net/{balancing → lb}/health_check_spec.rb +56 -21
- data/spec/net/{balancing → lb}/round_robin_spec.rb +0 -0
- data/spec/net/{balancing/sticky_policy_spec.rb → lb/sticky_spec.rb} +1 -1
- data/spec/net/request_balancer_spec.rb +161 -57
- data/spec/rack/request_logger_spec.rb +91 -27
- data/spec/rack/request_tracker_spec.rb +111 -1
- metadata +8 -5
@@ -11,7 +11,8 @@ describe RightSupport::Net::LB::HealthCheck do
|
|
11
11
|
@reset_time = 60
|
12
12
|
@policy = RightSupport::Net::LB::HealthCheck.new(
|
13
13
|
:yellow_states => @yellow_states,
|
14
|
-
:reset_time => @reset_time
|
14
|
+
:reset_time => @reset_time,
|
15
|
+
:health_check => lambda { |ep| true })
|
15
16
|
@policy.set_endpoints(@endpoints)
|
16
17
|
@trials = 2500
|
17
18
|
end
|
@@ -67,9 +68,11 @@ describe RightSupport::Net::LB::HealthCheck do
|
|
67
68
|
before(:each) do
|
68
69
|
@yellow_states = 3
|
69
70
|
@health_updates = []
|
70
|
-
@policy = RightSupport::Net::LB::HealthCheck.new(
|
71
|
-
|
72
|
-
|
71
|
+
@policy = RightSupport::Net::LB::HealthCheck.new(
|
72
|
+
:yellow_states => @yellow_states,
|
73
|
+
:reset_time => @reset_time,
|
74
|
+
:on_health_change => lambda { |health| @health_updates << health },
|
75
|
+
:health_check => lambda { |ep| true })
|
73
76
|
@policy.set_endpoints(@endpoints)
|
74
77
|
|
75
78
|
# put everyone into green state, then forget all health updates. this helps us write an
|
@@ -157,9 +160,10 @@ describe RightSupport::Net::LB::HealthCheck do
|
|
157
160
|
before(:each) do
|
158
161
|
@yellow_states = 3
|
159
162
|
@health_updates = []
|
160
|
-
@policy = RightSupport::Net::LB::HealthCheck.new(
|
161
|
-
|
162
|
-
|
163
|
+
@policy = RightSupport::Net::LB::HealthCheck.new(
|
164
|
+
:yellow_states => @yellow_states, :reset_time => @reset_time,
|
165
|
+
:on_health_change => lambda { |health| @health_updates << health },
|
166
|
+
:health_check => lambda { |ep| true })
|
163
167
|
@policy.set_endpoints(@endpoints)
|
164
168
|
|
165
169
|
# put everyone into green state, then forget all health updates. this helps us write an
|
@@ -212,7 +216,7 @@ describe RightSupport::Net::LB::HealthCheck do
|
|
212
216
|
@yellow_states.times { @policy.bad(@red, 0, Time.now) }
|
213
217
|
@policy.should have_red_endpoint(@red)
|
214
218
|
|
215
|
-
seen = find_empirical_distribution(@trials,@endpoints) do
|
219
|
+
seen = find_empirical_distribution(@trials,@endpoints) do
|
216
220
|
@policy.next
|
217
221
|
end
|
218
222
|
|
@@ -232,24 +236,53 @@ describe RightSupport::Net::LB::HealthCheck do
|
|
232
236
|
should_be_chosen_fairly(seen, @trials, @endpoints.size - 1)
|
233
237
|
end
|
234
238
|
|
235
|
-
it
|
236
|
-
|
237
|
-
|
239
|
+
it "eliminates bad endpoints during round robin selection" do
|
240
|
+
endpoints = [1, 2, 3, 4, 5]
|
241
|
+
policy = RightSupport::Net::LB::HealthCheck.new(
|
242
|
+
:yellow_states => 2,
|
243
|
+
:health_check => lambda { |ep| true })
|
244
|
+
policy.set_endpoints(endpoints)
|
245
|
+
policy.instance_variable_set(:@counter, 0)
|
246
|
+
breaking_bad = lambda { |ep| ep < 4 }
|
238
247
|
|
239
|
-
|
248
|
+
# first pass; initially all green, mark some yellow.
|
249
|
+
expected = [1, 2, 3, 4, 5]
|
240
250
|
actual = []
|
241
|
-
|
251
|
+
endpoints.size.times do
|
252
|
+
endpoint, need_health_check = policy.next
|
253
|
+
need_health_check.should be_false
|
254
|
+
if breaking_bad.call(endpoint)
|
255
|
+
policy.bad(endpoint, 0, Time.now) # go yellow
|
256
|
+
end
|
257
|
+
actual << endpoint
|
258
|
+
end
|
259
|
+
actual.should == expected
|
242
260
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
261
|
+
# second pass; some yellow, others green. yellows go red after being
|
262
|
+
# selected and are eliminated from subsequent round-robin selection.
|
263
|
+
expected = [1, 4, 5, 2, 3]
|
264
|
+
actual = []
|
247
265
|
endpoints.size.times do
|
248
|
-
endpoint,
|
249
|
-
|
266
|
+
endpoint, need_health_check = policy.next
|
267
|
+
if breaking_bad.call(endpoint)
|
268
|
+
# yellow is still viable but a health-check is requested.
|
269
|
+
need_health_check.should be_true
|
270
|
+
policy.bad(endpoint, 0, Time.now) # go red
|
271
|
+
else
|
272
|
+
need_health_check.should be_false
|
273
|
+
end
|
250
274
|
actual << endpoint
|
251
275
|
end
|
276
|
+
actual.should == expected
|
252
277
|
|
278
|
+
# third pass; green or red, no more yellow.
|
279
|
+
expected = [4, 5, 4, 5, 4]
|
280
|
+
actual = []
|
281
|
+
endpoints.size.times do
|
282
|
+
endpoint, need_health_check = policy.next
|
283
|
+
need_health_check.should be_false
|
284
|
+
actual << endpoint
|
285
|
+
end
|
253
286
|
actual.should == expected
|
254
287
|
end
|
255
288
|
end
|
@@ -350,8 +383,10 @@ describe RightSupport::Net::LB::HealthCheck do
|
|
350
383
|
context :set_endpoints do
|
351
384
|
context 'given endpoints stack does not exist' do
|
352
385
|
before(:each) do
|
353
|
-
@policy = RightSupport::Net::LB::HealthCheck.new(
|
354
|
-
|
386
|
+
@policy = RightSupport::Net::LB::HealthCheck.new(
|
387
|
+
:yellow_states => @yellow_states,
|
388
|
+
:reset_time => @reset_time,
|
389
|
+
:health_check => lambda { |ep| true })
|
355
390
|
end
|
356
391
|
|
357
392
|
it 'acts as initializer' do
|
File without changes
|
@@ -26,7 +26,7 @@ describe RightSupport::Net::LB::Sticky do
|
|
26
26
|
context 'given all servers are healthy' do
|
27
27
|
it 'sticks to chosen one' do
|
28
28
|
chance = 1.0
|
29
|
-
seen = find_empirical_distribution(@trials,@endpoints) do
|
29
|
+
seen = find_empirical_distribution(@trials,@endpoints) do
|
30
30
|
@policy.next
|
31
31
|
end
|
32
32
|
seen.each_pair do |_, count|
|
@@ -36,7 +36,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
36
36
|
|
37
37
|
exception = expect.first
|
38
38
|
count = expect.last
|
39
|
-
rb =
|
39
|
+
rb = described_class.new([1,2,3], :fatal=>fatal)
|
40
40
|
@tries = 0
|
41
41
|
|
42
42
|
code = lambda do
|
@@ -72,10 +72,11 @@ describe RightSupport::Net::RequestBalancer do
|
|
72
72
|
|
73
73
|
expect = number_of_endpoints
|
74
74
|
yellow_states = 4
|
75
|
-
rb =
|
76
|
-
|
77
|
-
|
78
|
-
|
75
|
+
rb = described_class.new(
|
76
|
+
(1..expect).to_a,
|
77
|
+
:policy => RightSupport::Net::LB::HealthCheck,
|
78
|
+
:health_check => test,
|
79
|
+
:yellow_states => yellow_states)
|
79
80
|
@health_checks = 0
|
80
81
|
tries = 0
|
81
82
|
l = lambda do
|
@@ -98,20 +99,25 @@ describe RightSupport::Net::RequestBalancer do
|
|
98
99
|
context :initialize do
|
99
100
|
it 'requires a list of endpoint URLs' do
|
100
101
|
lambda do
|
101
|
-
|
102
|
+
described_class.new(nil)
|
102
103
|
end.should raise_exception(ArgumentError)
|
103
104
|
end
|
104
105
|
|
105
106
|
context 'with Integer :retry option' do
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
107
|
+
[1, 2].each do |retry_value|
|
108
|
+
context "and :retry=#{retry_value}" do
|
109
|
+
it "stops after #{retry_value} total tries" do
|
110
|
+
lambda do
|
111
|
+
# note the legacy :retry integer value has no backoff.
|
112
|
+
@tries = 0
|
113
|
+
described_class.new([1, 2, 3], :retry => retry_value).request do |u|
|
114
|
+
@tries += 1
|
115
|
+
raise NoBigDeal
|
116
|
+
end
|
117
|
+
end.should raise_error
|
118
|
+
@tries.should == retry_value
|
112
119
|
end
|
113
|
-
end
|
114
|
-
@tries.should == 1
|
120
|
+
end
|
115
121
|
end
|
116
122
|
end
|
117
123
|
|
@@ -123,7 +129,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
123
129
|
@tries < 1
|
124
130
|
end
|
125
131
|
|
126
|
-
balancer =
|
132
|
+
balancer = described_class.new([1, 2, 3], :retry => proc)
|
127
133
|
lambda do
|
128
134
|
balancer.request do |u|
|
129
135
|
@tries += 1
|
@@ -133,12 +139,33 @@ describe RightSupport::Net::RequestBalancer do
|
|
133
139
|
|
134
140
|
@tries.should == 1
|
135
141
|
end
|
142
|
+
|
143
|
+
[1, 2].each do |max_attempts|
|
144
|
+
context "with backoff_retry_callback(#{max_attempts})" do
|
145
|
+
it "stops after #{max_attempts} total tries" do
|
146
|
+
start_time = ::Time.now
|
147
|
+
retry_proc = described_class.backoff_retry_callback(max_attempts)
|
148
|
+
lambda do
|
149
|
+
@tries = 0
|
150
|
+
described_class.new([1, 2, 3], :retry => retry_proc).request do |u|
|
151
|
+
@tries += 1
|
152
|
+
raise NoBigDeal
|
153
|
+
end
|
154
|
+
end.should raise_error
|
155
|
+
end_time = ::Time.now
|
156
|
+
@tries.should == max_attempts
|
157
|
+
if max_attempts == 2
|
158
|
+
((end_time - start_time) >= 2).should be_true # assert backoff
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
136
163
|
end
|
137
164
|
|
138
165
|
context ':fatal option' do
|
139
166
|
it 'has reasonable defaults' do
|
140
|
-
exceptions =
|
141
|
-
balancer =
|
167
|
+
exceptions = described_class::DEFAULT_FATAL_EXCEPTIONS - [SignalException]
|
168
|
+
balancer = described_class.new([1])
|
142
169
|
exceptions.each do |klass|
|
143
170
|
lambda do
|
144
171
|
balancer.request { |ep| raise klass }
|
@@ -150,13 +177,13 @@ describe RightSupport::Net::RequestBalancer do
|
|
150
177
|
it 'validates the arity' do
|
151
178
|
bad_lambda = lambda { |too, many, arguments| }
|
152
179
|
lambda do
|
153
|
-
|
180
|
+
described_class.new([1,2], :fatal=>bad_lambda)
|
154
181
|
end.should raise_error(ArgumentError)
|
155
182
|
end
|
156
183
|
|
157
184
|
it 'delegates to the Proc' do
|
158
185
|
always_retry = lambda { |e| false }
|
159
|
-
balancer =
|
186
|
+
balancer = described_class.new([1,2], :fatal=>always_retry)
|
160
187
|
|
161
188
|
lambda do
|
162
189
|
balancer.request do |ep|
|
@@ -174,7 +201,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
174
201
|
|
175
202
|
context 'with an Exception' do
|
176
203
|
it 'considers that class of Exception to be fatal' do
|
177
|
-
balancer =
|
204
|
+
balancer = described_class.new([1], :fatal=>BigDeal)
|
178
205
|
lambda do
|
179
206
|
balancer.request { |ep| raise BigDeal }
|
180
207
|
end.should raise_error(BigDeal)
|
@@ -184,7 +211,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
184
211
|
context 'with an Array' do
|
185
212
|
it 'considers any class in the array to be fatal' do
|
186
213
|
exceptions = [ArgumentError, BigDeal]
|
187
|
-
balancer =
|
214
|
+
balancer = described_class.new([1], :fatal=>exceptions)
|
188
215
|
exceptions.each do |klass|
|
189
216
|
lambda do
|
190
217
|
balancer.request { |ep| raise klass }
|
@@ -198,7 +225,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
198
225
|
it 'validates the arity' do
|
199
226
|
bad_lambda = lambda { |way, too, many, arguments| }
|
200
227
|
lambda do
|
201
|
-
|
228
|
+
described_class.new([1,2], :on_exception=>bad_lambda)
|
202
229
|
end.should raise_error(ArgumentError)
|
203
230
|
end
|
204
231
|
end
|
@@ -207,23 +234,23 @@ describe RightSupport::Net::RequestBalancer do
|
|
207
234
|
it 'accepts a Class' do
|
208
235
|
policy = RightSupport::Net::LB::RoundRobin
|
209
236
|
lambda {
|
210
|
-
|
237
|
+
described_class.new([1,2], :policy=>policy)
|
211
238
|
}.should_not raise_error
|
212
239
|
end
|
213
240
|
|
214
241
|
it 'accepts an object' do
|
215
242
|
policy = RightSupport::Net::LB::RoundRobin.new([1,2])
|
216
243
|
lambda {
|
217
|
-
|
244
|
+
described_class.new([1,2], :policy=>policy)
|
218
245
|
}.should_not raise_error
|
219
246
|
end
|
220
247
|
|
221
248
|
it 'checks for duck-type compatibility' do
|
222
249
|
lambda {
|
223
|
-
|
250
|
+
described_class.new([1,2], :policy=>String)
|
224
251
|
}.should raise_error
|
225
252
|
lambda {
|
226
|
-
|
253
|
+
described_class.new([1,2], :policy=>'I like cheese')
|
227
254
|
}.should raise_error
|
228
255
|
end
|
229
256
|
end
|
@@ -235,12 +262,12 @@ describe RightSupport::Net::RequestBalancer do
|
|
235
262
|
|
236
263
|
it 'accepts a block' do
|
237
264
|
lambda {
|
238
|
-
|
265
|
+
described_class.new([1,2], :health_check => @health_check)
|
239
266
|
}.should_not raise_error
|
240
267
|
end
|
241
268
|
|
242
269
|
it 'calls specified block' do
|
243
|
-
@balancer =
|
270
|
+
@balancer = described_class.new([1,2], :health_check => @health_check)
|
244
271
|
@options = @balancer.instance_variable_get("@options")
|
245
272
|
@options[:health_check].call(1).should be_eql("HealthCheck passed for 1!")
|
246
273
|
end
|
@@ -249,7 +276,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
249
276
|
|
250
277
|
context 'with default :health_check option' do
|
251
278
|
it 'calls default block' do
|
252
|
-
@balancer =
|
279
|
+
@balancer = described_class.new([1,2])
|
253
280
|
@options = @balancer.instance_variable_get("@options")
|
254
281
|
@options[:health_check].call(1).should be_true
|
255
282
|
end
|
@@ -263,7 +290,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
263
290
|
|
264
291
|
it 'accepts a block' do
|
265
292
|
lambda {
|
266
|
-
|
293
|
+
described_class.new([1,2], :on_health_change => @on_health_change)
|
267
294
|
}.should_not raise_error
|
268
295
|
end
|
269
296
|
end
|
@@ -272,7 +299,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
272
299
|
before(:each) do
|
273
300
|
flexmock(RightSupport::Net::DNS).should_receive(:resolve_with_hostnames).
|
274
301
|
with(['host1', 'host2']).and_return({'host1' => make_endpoint(['1.1.1.1', '2.2.2.2']), 'host2' => make_endpoint(['3.3.3.3'])})
|
275
|
-
@balancer =
|
302
|
+
@balancer = described_class.new(['host1', 'host2'], :resolve => 15)
|
276
303
|
end
|
277
304
|
|
278
305
|
it 'performs an initial resolution' do
|
@@ -291,26 +318,102 @@ describe RightSupport::Net::RequestBalancer do
|
|
291
318
|
context :request do
|
292
319
|
it 'requires a block' do
|
293
320
|
lambda do
|
294
|
-
|
321
|
+
described_class.new([1]).request
|
295
322
|
end.should raise_exception(ArgumentError)
|
296
323
|
end
|
297
324
|
|
298
|
-
|
299
|
-
list
|
325
|
+
context 'with a single thread' do
|
326
|
+
let(:list) { [1,2,3,4,5,6,7,8,9,10] }
|
327
|
+
|
328
|
+
subject { described_class.new(list) }
|
329
|
+
|
330
|
+
it 'retries until a request completes' do
|
331
|
+
queue = Queue.new
|
332
|
+
10.times do
|
333
|
+
x = subject.request do |l|
|
334
|
+
raise NoBigDeal, "Fall down go boom!" unless l == 5
|
335
|
+
l
|
336
|
+
end
|
337
|
+
x.should == 5
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
context 'with multiple threads and thread-safety enabled' do
|
343
|
+
let(:list) { [1,2,3,4,5,6,7,8,9,10] }
|
344
|
+
|
345
|
+
def boom(ep)
|
346
|
+
raise NoBigDeal, "Fall down go boom!" unless ep == 5
|
347
|
+
true
|
348
|
+
end
|
300
349
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
350
|
+
subject do
|
351
|
+
described_class.new(
|
352
|
+
list,
|
353
|
+
thread_safe: true,
|
354
|
+
policy: ::RightSupport::Net::LB::HealthCheck,
|
355
|
+
health_check: method(:boom))
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'retries until a request completes' do
|
359
|
+
count = list.size * 3
|
360
|
+
expected_responses = nil
|
361
|
+
expected_stats = list.inject({}) do |h, ep|
|
362
|
+
begin
|
363
|
+
boom(ep)
|
364
|
+
h[ep] = 'green'
|
365
|
+
expected_responses = [ep] * count
|
366
|
+
rescue NoBigDeal
|
367
|
+
h[ep] = 'red'
|
368
|
+
end
|
369
|
+
h
|
305
370
|
end
|
306
371
|
|
307
|
-
|
372
|
+
queue = Queue.new
|
373
|
+
count.times do
|
374
|
+
::Thread.new do
|
375
|
+
stop_time = ::Time.now + 10
|
376
|
+
loop do
|
377
|
+
begin
|
378
|
+
x = subject.request do |ep|
|
379
|
+
boom(ep)
|
380
|
+
ep
|
381
|
+
end
|
382
|
+
queue.push(x)
|
383
|
+
break
|
384
|
+
rescue ::RightSupport::Net::NoResult => e
|
385
|
+
# this can happen with too much thread contention for failing
|
386
|
+
# endpoints. the issue is that other threads keep snaking the
|
387
|
+
# only good endpoint away from this thread (i.e. keep
|
388
|
+
# incrementing the counter in health-check policy) until the
|
389
|
+
# allowed number of retries is exhausted. only when the other
|
390
|
+
# threads die can we be sure of getting the only good endpoint.
|
391
|
+
#
|
392
|
+
# keep trying for the purpose of this test but do not allow
|
393
|
+
# infinite retries.
|
394
|
+
if ::Time.now >= stop_time
|
395
|
+
queue.push(e)
|
396
|
+
break
|
397
|
+
end
|
398
|
+
rescue ::Exception => e
|
399
|
+
queue.push(e)
|
400
|
+
break
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
actual_responses = []
|
406
|
+
count.times do
|
407
|
+
actual_responses << queue.pop
|
408
|
+
end
|
409
|
+
actual_responses.should == expected_responses
|
410
|
+
subject.get_stats.should == expected_stats
|
308
411
|
end
|
309
412
|
end
|
310
413
|
|
311
414
|
it 'raises if no request completes' do
|
312
415
|
lambda do
|
313
|
-
|
416
|
+
described_class.request([1,2,3]) do |l|
|
314
417
|
raise NoBigDeal, "Fall down go boom!"
|
315
418
|
end
|
316
419
|
end.should raise_exception(RightSupport::Net::NoResult, /NoBigDeal/)
|
@@ -349,7 +452,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
349
452
|
context 'with default :fatal option' do
|
350
453
|
it 'retries most Ruby builtin errors' do
|
351
454
|
list = [1,2,3,4,5,6,7,8,9,10]
|
352
|
-
rb =
|
455
|
+
rb = described_class.new(list)
|
353
456
|
|
354
457
|
[IOError, SystemCallError, SocketError].each do |klass|
|
355
458
|
test_raise(nil, klass, [RightSupport::Net::NoResult, 3])
|
@@ -358,7 +461,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
358
461
|
|
359
462
|
it 'does not retry program errors' do
|
360
463
|
list = [1,2,3,4,5,6,7,8,9,10]
|
361
|
-
rb =
|
464
|
+
rb = described_class.new(list)
|
362
465
|
|
363
466
|
[ArgumentError, LoadError, NameError].each do |klass|
|
364
467
|
test_raise(nil, klass, [klass, 1])
|
@@ -372,7 +475,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
372
475
|
|
373
476
|
it 'does not retry HTTP 4xx other than timeout' do
|
374
477
|
list = [1,2,3,4,5,6,7,8,9,10]
|
375
|
-
rb =
|
478
|
+
rb = described_class.new(list)
|
376
479
|
|
377
480
|
codes = [401, 402, 403, 404, 405, 406, 407, 409]
|
378
481
|
codes.each do |code|
|
@@ -384,7 +487,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
384
487
|
|
385
488
|
context 'with default :retry option' do
|
386
489
|
it 'marks endpoints as bad if they encounter retryable errors' do
|
387
|
-
rb =
|
490
|
+
rb = described_class.new([1,2,3], :policy => RightSupport::Net::LB::HealthCheck, :health_check => Proc.new {|endpoint| false})
|
388
491
|
expect = rb.get_stats
|
389
492
|
codes = [401, 402, 403, 404, 405, 406, 407, 408, 409]
|
390
493
|
codes.each do |code|
|
@@ -397,7 +500,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
397
500
|
end
|
398
501
|
|
399
502
|
it 'does not mark endpoints as bad if they raise fatal errors' do
|
400
|
-
rb =
|
503
|
+
rb = described_class.new([1,2,3], :policy => RightSupport::Net::LB::HealthCheck, :health_check => Proc.new {|endpoint| false})
|
401
504
|
codes = [401, 402, 403, 404, 405, 406, 407, 409]
|
402
505
|
codes.each do |code|
|
403
506
|
lambda do
|
@@ -420,7 +523,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
420
523
|
@callback.should_receive(:respond_to?).with(:call).and_return(true)
|
421
524
|
@callback.should_receive(:respond_to?).with(:arity).and_return(true)
|
422
525
|
@callback.should_receive(:arity).and_return(3)
|
423
|
-
@rb =
|
526
|
+
@rb = described_class.new(@list, :fatal=>BigDeal, :on_exception=>@callback)
|
424
527
|
end
|
425
528
|
|
426
529
|
it 'calls me back with fatal exceptions' do
|
@@ -442,12 +545,12 @@ describe RightSupport::Net::RequestBalancer do
|
|
442
545
|
context 'given a class-level logger' do
|
443
546
|
before(:all) do
|
444
547
|
@logger = Logger.new(StringIO.new)
|
445
|
-
|
548
|
+
described_class.logger = @logger
|
446
549
|
RightSupport::Net::LB::HealthCheck.logger = @logger
|
447
550
|
end
|
448
551
|
|
449
552
|
after(:all) do
|
450
|
-
|
553
|
+
described_class.logger = nil
|
451
554
|
end
|
452
555
|
|
453
556
|
context 'when a retryable exception is raised' do
|
@@ -455,7 +558,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
455
558
|
flexmock(@logger).should_receive(:error).times(4)
|
456
559
|
|
457
560
|
lambda {
|
458
|
-
balancer =
|
561
|
+
balancer = described_class.new([1,2,3])
|
459
562
|
balancer.request do |ep|
|
460
563
|
raise NoBigDeal, "Too many cows on the moon"
|
461
564
|
end
|
@@ -471,7 +574,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
471
574
|
flexmock(@logger).should_receive(:info).times(8)
|
472
575
|
|
473
576
|
lambda {
|
474
|
-
balancer =
|
577
|
+
balancer = described_class.new([1,2,3,4], :policy => RightSupport::Net::LB::HealthCheck, :health_check => health_check)
|
475
578
|
balancer.request do |ep|
|
476
579
|
raise "Bad Endpoint"
|
477
580
|
end
|
@@ -498,7 +601,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
498
601
|
|
499
602
|
it 'resolves ip addresses for specified list of endpoints' do
|
500
603
|
@dns.should_receive(:resolve_with_hostnames).with(@endpoints).and_return(@resolved_set_1)
|
501
|
-
@rb =
|
604
|
+
@rb = described_class.new(@endpoints, :resolve => 15)
|
502
605
|
|
503
606
|
@rb.request { true }
|
504
607
|
@policy = @rb.instance_variable_get("@policy")
|
@@ -507,7 +610,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
507
610
|
|
508
611
|
it 're-resolves list of ip addresses if TTL is expired' do
|
509
612
|
@dns.should_receive(:resolve_with_hostnames).with(@endpoints).twice.and_return(@resolved_set_1, @resolved_set_2)
|
510
|
-
@rb =
|
613
|
+
@rb = described_class.new(@endpoints, :resolve => 15)
|
511
614
|
|
512
615
|
@rb.request { true }
|
513
616
|
@policy = @rb.instance_variable_get("@policy")
|
@@ -524,7 +627,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
524
627
|
before(:each) do
|
525
628
|
@endpoints = [1,2,3,4,5,6]
|
526
629
|
@exceptions = [BigDeal, NoBigDeal, OtherTestException]
|
527
|
-
@rb =
|
630
|
+
@rb = described_class.new(@endpoints)
|
528
631
|
@tries = 0
|
529
632
|
begin
|
530
633
|
@rb.request do |ep|
|
@@ -564,7 +667,7 @@ describe RightSupport::Net::RequestBalancer do
|
|
564
667
|
expected_hash = {}
|
565
668
|
list = [1,2,3,4]
|
566
669
|
list.each { |k| expected_hash[k] = 'n/a' }
|
567
|
-
rb =
|
670
|
+
rb = described_class.new(list)
|
568
671
|
|
569
672
|
rb.get_stats.should_not be_nil
|
570
673
|
rb.get_stats.should == expected_hash
|
@@ -575,9 +678,10 @@ describe RightSupport::Net::RequestBalancer do
|
|
575
678
|
it 'returns stats in an endpoint-keyed hash' do
|
576
679
|
expected_hash = {}
|
577
680
|
list = [1,2,3,4]
|
578
|
-
rb =
|
579
|
-
|
580
|
-
|
681
|
+
rb = described_class.new(
|
682
|
+
list,
|
683
|
+
:policy => RightSupport::Net::LB::HealthCheck,
|
684
|
+
:health_check => Proc.new {|endpoint| "HealthCheck passed for #{endpoint}!"})
|
581
685
|
rb.get_stats.should_not be_nil
|
582
686
|
rb.get_stats.should_not == expected_hash
|
583
687
|
end
|