right_agent 2.1.5-x86-mingw32 → 2.2.0-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/right_agent/agent_tag_manager.rb +17 -9
- data/lib/right_agent/clients/api_client.rb +28 -27
- data/lib/right_agent/clients/balanced_http_client.rb +25 -5
- data/lib/right_agent/clients/base_retry_client.rb +76 -42
- data/lib/right_agent/clients/blocking_client.rb +11 -1
- data/lib/right_agent/clients/non_blocking_client.rb +32 -9
- data/lib/right_agent/clients/right_http_client.rb +14 -8
- data/lib/right_agent/clients/router_client.rb +41 -14
- data/lib/right_agent/command/command_client.rb +1 -0
- data/lib/right_agent/http_exceptions.rb +6 -1
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +2 -2
- data/lib/right_agent/offline_handler.rb +22 -9
- data/lib/right_agent/retryable_request.rb +18 -12
- data/lib/right_agent/scripts/agent_controller.rb +9 -3
- data/lib/right_agent/sender.rb +94 -61
- data/right_agent.gemspec +2 -2
- data/spec/agent_tag_manager_spec.rb +59 -14
- data/spec/clients/api_client_spec.rb +48 -36
- data/spec/clients/balanced_http_client_spec.rb +46 -2
- data/spec/clients/base_retry_client_spec.rb +118 -48
- data/spec/clients/blocking_client_spec.rb +16 -0
- data/spec/clients/non_blocking_client_spec.rb +43 -6
- data/spec/clients/router_client_spec.rb +54 -49
- data/spec/http_exceptions_spec.rb +7 -0
- data/spec/offline_handler_spec.rb +22 -11
- data/spec/retryable_request_spec.rb +35 -20
- data/spec/sender_spec.rb +185 -122
- metadata +3 -3
@@ -203,6 +203,12 @@ describe RightScale::BlockingClient do
|
|
203
203
|
result.should == [@result, 200, @body, @headers]
|
204
204
|
end
|
205
205
|
|
206
|
+
it "stores the connection" do
|
207
|
+
@http_client.should_receive(:get).with(@host + @path + @query, @request_options).and_return(@response).once
|
208
|
+
@client.request(:get, @path, @host, @connect_options, @request_options)
|
209
|
+
@client.connections[@path].should == {:host => @host, :path => @path, :expires_at => @later + 5}
|
210
|
+
end
|
211
|
+
|
206
212
|
it "returns nil if response is nil" do
|
207
213
|
@http_client.should_receive(:get).with(@host + @path + @query, @request_options).and_return(nil).once
|
208
214
|
result = @client.request(:get, @path, @host, @connect_options, @request_options)
|
@@ -261,5 +267,15 @@ describe RightScale::BlockingClient do
|
|
261
267
|
result.should == [nil, nil, nil, nil]
|
262
268
|
end
|
263
269
|
end
|
270
|
+
|
271
|
+
context :close do
|
272
|
+
it "deletes all persistent connections" do
|
273
|
+
@http_client.should_receive(:get).with(@host + @path + @query, @request_options).and_return(@response).once
|
274
|
+
@client.request(:get, @path, @host, @connect_options, @request_options)
|
275
|
+
@client.connections.should_not be_empty
|
276
|
+
@client.close("terminating").should be true
|
277
|
+
@client.connections.should be_empty
|
278
|
+
end
|
279
|
+
end
|
264
280
|
end
|
265
281
|
end
|
@@ -264,15 +264,15 @@ describe RightScale::NonBlockingClient do
|
|
264
264
|
should raise_error(RightScale::HttpExceptions::InternalServerError)
|
265
265
|
end
|
266
266
|
|
267
|
-
it "converts Errno::ETIMEDOUT error to
|
268
|
-
@headers.http_status =
|
267
|
+
it "converts Errno::ETIMEDOUT error to 408 RequestTimeout" do
|
268
|
+
@headers.http_status = 408
|
269
269
|
@response.should_receive(:errback).and_yield.once
|
270
270
|
@response.should_receive(:error).and_return(Errno::ETIMEDOUT)
|
271
|
-
@fiber.should_receive(:resume).with(
|
272
|
-
flexmock(Fiber).should_receive(:yield).and_return([
|
271
|
+
@fiber.should_receive(:resume).with(408, "Request timeout").once
|
272
|
+
flexmock(Fiber).should_receive(:yield).and_return([408, "Request timeout"]).once
|
273
273
|
flexmock(EM::HttpRequest).should_receive(:new).with(@host, @connect_options).and_return(@request).once
|
274
274
|
lambda { @client.request(:get, @path, @host, @connect_options, @request_options) }.
|
275
|
-
should raise_error(RightScale::HttpExceptions::
|
275
|
+
should raise_error(RightScale::HttpExceptions::RequestTimeout)
|
276
276
|
end
|
277
277
|
|
278
278
|
it "stores the connection if keepalive enabled" do
|
@@ -351,7 +351,7 @@ describe RightScale::NonBlockingClient do
|
|
351
351
|
end
|
352
352
|
|
353
353
|
it "stops polling if there is an error" do
|
354
|
-
@response.should_receive(:error).and_return("some error").
|
354
|
+
@response.should_receive(:error).and_return("some error").once
|
355
355
|
@response.should_receive(:errback).and_yield.once
|
356
356
|
@fiber.should_receive(:resume).with(500, "some error").once
|
357
357
|
@client.send(:poll_again, @fiber, @request, @request_options, @stop_at).should be true
|
@@ -374,6 +374,43 @@ describe RightScale::NonBlockingClient do
|
|
374
374
|
end
|
375
375
|
end
|
376
376
|
end
|
377
|
+
|
378
|
+
context :close do
|
379
|
+
it "closes all persistent connections" do
|
380
|
+
@request_options.merge!(:keepalive => true)
|
381
|
+
flexmock(EM::HttpRequest).should_receive(:new).and_return(@request).once
|
382
|
+
@client.request(:get, @path, @host, @connect_options, @request_options)
|
383
|
+
@request.should_receive(:close).with("terminating").once
|
384
|
+
@client.connections.should_not be_empty
|
385
|
+
@client.close("terminating").should be true
|
386
|
+
@client.connections.should be_empty
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
context :handle_error do
|
392
|
+
before(:each) do
|
393
|
+
@options = {}
|
394
|
+
@client = RightScale::NonBlockingClient.new(@options)
|
395
|
+
end
|
396
|
+
|
397
|
+
["terminating", "reconnecting"].each do |error|
|
398
|
+
it "converts #{error} error to a 200 OK" do
|
399
|
+
@client.send(:handle_error, :get, error).should == [200, nil]
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
it "converts Errno::ETIMEDOUT to 408 RequestTimeout" do
|
404
|
+
@client.send(:handle_error, :get, Errno::ETIMEDOUT).should == [408, "Request timeout"]
|
405
|
+
end
|
406
|
+
|
407
|
+
it "converts error to 500 InternalServerError by default" do
|
408
|
+
@client.send(:handle_error, :get, "failed").should == [500, "failed"]
|
409
|
+
end
|
410
|
+
|
411
|
+
it "generates error message for 500 InternalServerError if none specified" do
|
412
|
+
@client.send(:handle_error, :get, nil).should == [500, "HTTP connection failure for GET"]
|
413
|
+
end
|
377
414
|
end
|
378
415
|
|
379
416
|
context :beautify_headers do
|
@@ -34,7 +34,7 @@ describe RightScale::RouterClient do
|
|
34
34
|
@log.should_receive(:warning).by_default.and_return { |m| raise RightScale::Log.format(*m) }
|
35
35
|
@timer = flexmock("timer", :cancel => true).by_default
|
36
36
|
flexmock(EM::Timer).should_receive(:new).and_return(@timer).by_default
|
37
|
-
@http_client = flexmock("http client", :get => true, :check_health => true).by_default
|
37
|
+
@http_client = flexmock("http client", :get => true, :check_health => true, :close => true).by_default
|
38
38
|
flexmock(RightScale::BalancedHttpClient).should_receive(:new).and_return(@http_client).by_default
|
39
39
|
@websocket = WebSocketClientMock.new
|
40
40
|
flexmock(Faye::WebSocket::Client).should_receive(:new).and_return(@websocket).by_default
|
@@ -83,44 +83,41 @@ describe RightScale::RouterClient do
|
|
83
83
|
@action = "bar"
|
84
84
|
@payload = {:some => "data"}
|
85
85
|
@target = "rs-agent-2-2"
|
86
|
-
@token = "random token"
|
87
86
|
@params = {
|
88
87
|
:type => @type,
|
89
88
|
:payload => @payload,
|
90
89
|
:target => @target }
|
91
90
|
end
|
92
91
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
it "does not require token" do
|
101
|
-
flexmock(@client).should_receive(:make_request).with(:post, "/push", @params, @action, nil).
|
102
|
-
and_return(nil).once
|
103
|
-
@client.push(@type, @payload, @target).should be nil
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
context :request do
|
108
|
-
it "makes post request to router" do
|
109
|
-
flexmock(@client).should_receive(:make_request).with(:post, "/request", @params, @action, @token).
|
110
|
-
and_return(nil).once
|
111
|
-
@client.request(@type, @payload, @target, @token)
|
112
|
-
end
|
92
|
+
[:push, :request].each do |kind|
|
93
|
+
context kind do
|
94
|
+
it "makes post request to router" do
|
95
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/#{kind}", @params, @action, {}).and_return(nil).once
|
96
|
+
@client.send(kind, @type, @payload, @target).should be nil
|
97
|
+
end
|
113
98
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
99
|
+
it "applies request options" do
|
100
|
+
options = {:request_uuid => "uuid", :time_to_live => 60}
|
101
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/#{kind}", @params, @action, options).and_return(nil).once
|
102
|
+
@client.send(kind, @type, @payload, @target, options).should be nil
|
103
|
+
end
|
118
104
|
end
|
119
105
|
end
|
120
106
|
end
|
121
107
|
|
122
108
|
context "events" do
|
123
109
|
|
110
|
+
def when_in_listen_state(state, checks = nil, failures = 0)
|
111
|
+
flexmock(EM).should_receive(:next_tick).by_default
|
112
|
+
flexmock(EM::Timer).should_receive(:new).and_return(@timer).by_default
|
113
|
+
@client.send(:update_listen_state, state)
|
114
|
+
@client.instance_variable_set(:@listen_checks, checks) if checks
|
115
|
+
@client.instance_variable_set(:@listen_failures, failures)
|
116
|
+
@client.instance_variable_set(:@connect_interval, 30)
|
117
|
+
@client.instance_variable_set(:@reconnect_interval, 2)
|
118
|
+
state
|
119
|
+
end
|
120
|
+
|
124
121
|
before(:each) do
|
125
122
|
@handler = lambda { |_| }
|
126
123
|
@later = Time.at(@now = Time.now)
|
@@ -143,8 +140,8 @@ describe RightScale::RouterClient do
|
|
143
140
|
end
|
144
141
|
|
145
142
|
it "makes post request by default" do
|
146
|
-
flexmock(@client).should_receive(:make_request).with(:post, "/notify", @params, "notify",
|
147
|
-
{:filter_params => ["event"]}).once
|
143
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/notify", @params, "notify",
|
144
|
+
{:request_uuid => "uuid", :filter_params => ["event"]}).once
|
148
145
|
@client.notify(@event, @routing_keys).should be true
|
149
146
|
end
|
150
147
|
end
|
@@ -223,17 +220,6 @@ describe RightScale::RouterClient do
|
|
223
220
|
end
|
224
221
|
|
225
222
|
context :listen_loop do
|
226
|
-
def when_in_listen_state(state, checks = nil, failures = 0)
|
227
|
-
flexmock(EM).should_receive(:next_tick).by_default
|
228
|
-
flexmock(EM::Timer).should_receive(:new).and_return(@timer).by_default
|
229
|
-
@client.send(:update_listen_state, state)
|
230
|
-
@client.instance_variable_set(:@listen_checks, checks) if checks
|
231
|
-
@client.instance_variable_set(:@listen_failures, failures)
|
232
|
-
@client.instance_variable_set(:@connect_interval, 30)
|
233
|
-
@client.instance_variable_set(:@reconnect_interval, 2)
|
234
|
-
state
|
235
|
-
end
|
236
|
-
|
237
223
|
context "in :choose state" do
|
238
224
|
it "chooses listen method" do
|
239
225
|
when_in_listen_state(:choose)
|
@@ -357,22 +343,41 @@ describe RightScale::RouterClient do
|
|
357
343
|
end
|
358
344
|
end
|
359
345
|
|
346
|
+
it "waits required amount of time before looping" do
|
347
|
+
when_in_listen_state(:choose)
|
348
|
+
flexmock(@client).should_receive(:listen_loop_wait).with(@later + 1, 0, @routing_keys, @handler).and_return(true).once
|
349
|
+
@client.send(:listen_loop, @routing_keys, &@handler).should be true
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context :listen_loop_wait do
|
360
354
|
it "uses next_tick for next loop if interval is 0" do
|
361
355
|
when_in_listen_state(:choose)
|
362
356
|
@client.instance_variable_get(:@listen_interval).should == 0
|
363
357
|
flexmock(EM).should_receive(:next_tick).and_yield.once
|
364
|
-
flexmock(EM::Timer).should_receive(:new).
|
365
|
-
@client.
|
366
|
-
@client.
|
358
|
+
flexmock(EM::Timer).should_receive(:new).never
|
359
|
+
flexmock(@client).should_receive(:listen_loop).with(@routing_keys, @handler).once
|
360
|
+
@client.send(:listen_loop_wait, 0, @later, @routing_keys, &@handler).should be true
|
367
361
|
end
|
368
362
|
|
369
363
|
it "otherwise uses timer for next loop" do
|
370
364
|
when_in_listen_state(:long_poll)
|
371
|
-
|
372
|
-
flexmock(EM::Timer).should_receive(:new).with(
|
365
|
+
@client.instance_variable_set(:@listen_interval, 9)
|
366
|
+
flexmock(EM::Timer).should_receive(:new).with(9, Proc).and_return(@timer).and_yield.once
|
373
367
|
flexmock(EM).should_receive(:next_tick).never
|
374
|
-
@client.
|
375
|
-
@client.
|
368
|
+
flexmock(@client).should_receive(:listen_loop).with(@routing_keys, @handler).once
|
369
|
+
@client.send(:listen_loop_wait, @later - 9, 9, @routing_keys, &@handler).should be true
|
370
|
+
end
|
371
|
+
|
372
|
+
it "waits some more if interval has changed while waiting" do
|
373
|
+
when_in_listen_state(:long_poll)
|
374
|
+
@client.instance_variable_set(:@listen_interval, 3)
|
375
|
+
flexmock(EM::Timer).should_receive(:new).with(1, Proc).and_return(@timer).and_yield.once.ordered
|
376
|
+
flexmock(EM::Timer).should_receive(:new).with(2, Proc).and_return(@timer).and_yield.once.ordered
|
377
|
+
flexmock(EM::Timer).should_receive(:new).with(1, Proc).and_return(@timer).and_yield.once.ordered
|
378
|
+
flexmock(EM).should_receive(:next_tick).never
|
379
|
+
flexmock(@client).should_receive(:listen_loop).with(@routing_keys, @handler).once
|
380
|
+
@client.send(:listen_loop_wait, @later, 1, @routing_keys, &@handler).should be true
|
376
381
|
end
|
377
382
|
end
|
378
383
|
|
@@ -429,7 +434,7 @@ describe RightScale::RouterClient do
|
|
429
434
|
end
|
430
435
|
end
|
431
436
|
|
432
|
-
[502, 503].each do |code|
|
437
|
+
[408, 502, 503].each do |code|
|
433
438
|
it "chooses to connect immediately if previous close code #{code} indicates router not responding" do
|
434
439
|
@client.instance_variable_set(:@close_code, RightScale::RouterClient::PROTOCOL_ERROR_CLOSE)
|
435
440
|
@client.instance_variable_set(:@close_reason, "Unexpected response code: #{code}")
|
@@ -676,13 +681,13 @@ describe RightScale::RouterClient do
|
|
676
681
|
it "makes listen request to router" do
|
677
682
|
flexmock(@client).should_receive(:make_request).with(:poll, "/listen",
|
678
683
|
on { |a| a[:wait_time].should == 55 && !a.key?(:routing_keys) &&
|
679
|
-
a[:timestamp] == @later.to_f }, "listen",
|
684
|
+
a[:timestamp] == @later.to_f }, "listen", Hash).and_return([@event]).once
|
680
685
|
@client.send(:long_poll, @routing_keys, @ack, &@handler)
|
681
686
|
end
|
682
687
|
|
683
688
|
it "uses listen timeout for request poll timeout and connect interval for request timeout" do
|
684
689
|
@client.instance_variable_set(:@connect_interval, 300)
|
685
|
-
flexmock(@client).should_receive(:make_request).with(:poll, "/listen", Hash, "listen",
|
690
|
+
flexmock(@client).should_receive(:make_request).with(:poll, "/listen", Hash, "listen",
|
686
691
|
{:poll_timeout => 60, :request_timeout => 300}).and_return([@event]).once
|
687
692
|
@client.send(:long_poll, @routing_keys, @ack, &@handler)
|
688
693
|
end
|
@@ -101,6 +101,13 @@ describe RightScale::HttpExceptions do
|
|
101
101
|
bad_request = RestClient::Exceptions::EXCEPTIONS_MAP[400].new(nil, 400)
|
102
102
|
RightScale::HttpExceptions.convert(bad_request).should be_a RightScale::HttpExceptions::BadRequest
|
103
103
|
end
|
104
|
+
|
105
|
+
it "assigns status code 408 to RequestTimeout" do
|
106
|
+
request_timeout = RestClient::Exceptions::EXCEPTIONS_MAP[408].new
|
107
|
+
exception = RightScale::HttpExceptions.convert(request_timeout)
|
108
|
+
exception.should be_a RightScale::HttpExceptions::RequestTimeout
|
109
|
+
exception.http_code.should == 408
|
110
|
+
end
|
104
111
|
end
|
105
112
|
|
106
113
|
end # RightScale::HttpExceptions
|
@@ -192,14 +192,18 @@ describe RightScale::OfflineHandler do
|
|
192
192
|
@type = "/foo/bar"
|
193
193
|
@payload = {:pay => "load"}
|
194
194
|
@target = "target"
|
195
|
+
@token = "token"
|
196
|
+
@now = Time.now
|
197
|
+
flexmock(Time).should_receive(:now).and_return(@now)
|
198
|
+
@expires_at = @now + 25
|
195
199
|
@callback = lambda { |_| }
|
196
200
|
end
|
197
201
|
|
198
202
|
it "queues request at head of queue if still initializing" do
|
199
203
|
@handler.init
|
200
|
-
@handler.queue_request(@kind, @type, @payload, "target1", @callback).should be_true
|
204
|
+
@handler.queue_request(@kind, @type, @payload, "target1", "token1", @expires_at, &@callback).should be_true
|
201
205
|
@handler.queue.size.should == 1
|
202
|
-
@handler.queue_request(@kind, @type, @payload, "target2", @callback).should be_true
|
206
|
+
@handler.queue_request(@kind, @type, @payload, "target2", "token2", @expires_at, &@callback).should be_true
|
203
207
|
@handler.queue.size.should == 2
|
204
208
|
@handler.queue.first[:target] == "target2"
|
205
209
|
end
|
@@ -207,9 +211,9 @@ describe RightScale::OfflineHandler do
|
|
207
211
|
it "queues request at end of queue if no longer initializing" do
|
208
212
|
@handler.init
|
209
213
|
@handler.start
|
210
|
-
@handler.queue_request(@kind, @type, @payload, "target1", @callback)
|
214
|
+
@handler.queue_request(@kind, @type, @payload, "target1", "token1", @expires_at, &@callback)
|
211
215
|
@handler.queue.size.should == 1
|
212
|
-
@handler.queue_request(@kind, @type, @payload, "target2", @callback)
|
216
|
+
@handler.queue_request(@kind, @type, @payload, "target2", "token2", @expires_at, &@callback)
|
213
217
|
@handler.queue.size.should == 2
|
214
218
|
@handler.queue.first[:target] == "target1"
|
215
219
|
end
|
@@ -219,7 +223,7 @@ describe RightScale::OfflineHandler do
|
|
219
223
|
@handler.start
|
220
224
|
flexmock(@handler).should_receive(:vote_to_restart).once
|
221
225
|
RightScale::OfflineHandler::MAX_QUEUED_REQUESTS.times do |i|
|
222
|
-
@handler.queue_request(@kind, @type, @payload, @target, @callback)
|
226
|
+
@handler.queue_request(@kind, @type, @payload, @target, @token, @expires_at, &@callback)
|
223
227
|
end
|
224
228
|
end
|
225
229
|
end
|
@@ -241,6 +245,10 @@ describe RightScale::OfflineHandler do
|
|
241
245
|
@type = "/foo/bar"
|
242
246
|
@payload = {:pay => "load"}
|
243
247
|
@target = "target"
|
248
|
+
@token = "token"
|
249
|
+
@now = Time.now
|
250
|
+
flexmock(Time).should_receive(:now).and_return(@now)
|
251
|
+
@expires_at = (@now + 25).to_i
|
244
252
|
@result = nil
|
245
253
|
@callback = lambda { |result| @result = result }
|
246
254
|
end
|
@@ -251,16 +259,19 @@ describe RightScale::OfflineHandler do
|
|
251
259
|
@handler.start
|
252
260
|
flexmock(@handler).should_receive(:start_timer)
|
253
261
|
@handler.enable
|
254
|
-
@handler.queue_request(:send_push, @type, @payload, @target,
|
255
|
-
@handler.queue_request(:send_request, @type, @payload, @target, @callback)
|
256
|
-
@handler.
|
257
|
-
|
258
|
-
|
259
|
-
@sender.should_receive(:
|
262
|
+
@handler.queue_request(:send_push, @type, @payload, @target, @token, 0)
|
263
|
+
@handler.queue_request(:send_request, @type, @payload, @target, @token, @expires_at, &@callback)
|
264
|
+
@handler.queue_request(:send_request, @type, @payload, @target, @token, @now.to_i, &@callback)
|
265
|
+
@handler.queue.size.should == 3
|
266
|
+
flexmock(EM).should_receive(:next_tick).and_yield.twice
|
267
|
+
@sender.should_receive(:send_push).with(@type, @payload, @target, {:token => @token}).once.ordered
|
268
|
+
@sender.should_receive(:send_request).
|
269
|
+
with(@type, @payload, @target, {:token => @token, :time_to_live => 25}, Proc).and_yield("result").once.ordered
|
260
270
|
flexmock(EM).should_receive(:add_timer).and_yield.once
|
261
271
|
log = flexmock(RightScale::Log)
|
262
272
|
log.should_receive(:info).with(/Connection to RightNet re-established/).once.ordered
|
263
273
|
log.should_receive(:info).with(/Starting to flush request queue/).once.ordered
|
274
|
+
log.should_receive(:info).with(/Dropping queued request/).once.ordered
|
264
275
|
log.should_receive(:info).with(/Request queue flushed/).once.ordered
|
265
276
|
@handler.disable.should be_true
|
266
277
|
end
|
@@ -35,6 +35,7 @@ describe RightScale::RetryableRequest do
|
|
35
35
|
RightScale.module_eval('OldSender = Sender')
|
36
36
|
end
|
37
37
|
RightScale.module_eval('Sender = SenderMock')
|
38
|
+
@options = {:time_to_live => RightScale::RetryableRequest::DEFAULT_TIMEOUT}
|
38
39
|
end
|
39
40
|
|
40
41
|
after(:all) do
|
@@ -48,7 +49,7 @@ describe RightScale::RetryableRequest do
|
|
48
49
|
context 'when :targets => nil' do
|
49
50
|
it 'should send target-less requests' do
|
50
51
|
request = RightScale::RetryableRequest.new('type', 'payload')
|
51
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
52
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
52
53
|
and_yield(RightScale::OperationResult.non_delivery('test')).once
|
53
54
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
54
55
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
@@ -59,7 +60,7 @@ describe RightScale::RetryableRequest do
|
|
59
60
|
context 'when one target is specified' do
|
60
61
|
it 'should send a targeted request' do
|
61
62
|
request = RightScale::RetryableRequest.new('type', 'payload', :targets => ["rs-agent-1-1"])
|
62
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', {:agent_id => "rs-agent-1-1"}, Proc).
|
63
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', {:agent_id => "rs-agent-1-1"}, @options, Proc).
|
63
64
|
and_yield(RightScale::OperationResult.non_delivery('test')).once
|
64
65
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
65
66
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
@@ -70,10 +71,12 @@ describe RightScale::RetryableRequest do
|
|
70
71
|
context 'when many targets are specified' do
|
71
72
|
it 'should choose a random target' do
|
72
73
|
request = RightScale::RetryableRequest.new('type', 'payload', :targets => ["rs-agent-1-1", "rs-agent-2-2", "rs-agent-3-3"])
|
73
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).and_return do |type, payload, target, block|
|
74
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).and_return do |type, payload, target, options, block|
|
74
75
|
type.should == 'type'
|
75
76
|
payload.should == 'payload'
|
76
77
|
["rs-agent-1-1", "rs-agent-2-2", "rs-agent-3-3"].should include(target[:agent_id])
|
78
|
+
options[:token].should == nil
|
79
|
+
options[:time_to_live].should == @options[:time_to_live]
|
77
80
|
block.call(RightScale::OperationResult.non_delivery('test'))
|
78
81
|
end
|
79
82
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
@@ -89,7 +92,7 @@ describe RightScale::RetryableRequest do
|
|
89
92
|
context 'when not specified' do
|
90
93
|
it 'should fail if receives error response' do
|
91
94
|
request = RightScale::RetryableRequest.new('type', 'payload')
|
92
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
95
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
93
96
|
and_yield(RightScale::OperationResult.error('test')).once
|
94
97
|
flexmock(request).should_receive(:fail).once
|
95
98
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
@@ -100,7 +103,7 @@ describe RightScale::RetryableRequest do
|
|
100
103
|
context 'when specified as true' do
|
101
104
|
it 'should retry if receives error response' do
|
102
105
|
request = RightScale::RetryableRequest.new('type', 'payload', :retry_on_error => true)
|
103
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
106
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
104
107
|
and_yield(RightScale::OperationResult.error('test')).once
|
105
108
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
106
109
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
@@ -109,7 +112,7 @@ describe RightScale::RetryableRequest do
|
|
109
112
|
|
110
113
|
it 'should ignore duplicate responses' do
|
111
114
|
request = RightScale::RetryableRequest.new('type', 'payload', :retry_on_error => true)
|
112
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).and_return do |t, p, tgt, b|
|
115
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).and_return do |t, p, tgt, opts, b|
|
113
116
|
5.times { b.call(RightScale::OperationResult.success('test')) }
|
114
117
|
end
|
115
118
|
flexmock(request).should_receive(:fail).never
|
@@ -122,7 +125,7 @@ describe RightScale::RetryableRequest do
|
|
122
125
|
it 'should never retry after cancel response' do
|
123
126
|
request = RightScale::RetryableRequest.new('type', 'payload', :retry_on_error => true)
|
124
127
|
flexmock(RightScale::Log).should_receive(:info).with("Request type canceled (enough already)").once
|
125
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
128
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
126
129
|
and_yield(RightScale::OperationResult.cancel('enough already')).once
|
127
130
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
128
131
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).never
|
@@ -139,7 +142,7 @@ describe RightScale::RetryableRequest do
|
|
139
142
|
request = RightScale::RetryableRequest.new('type', 'payload')
|
140
143
|
flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
|
141
144
|
flexmock(RightScale::Log).should_receive(:info).with("Request non-delivery (test) for type").once
|
142
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
145
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
143
146
|
and_yield(RightScale::OperationResult.non_delivery('test')).once
|
144
147
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
145
148
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
@@ -150,7 +153,7 @@ describe RightScale::RetryableRequest do
|
|
150
153
|
request = RightScale::RetryableRequest.new('type', 'payload')
|
151
154
|
flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
|
152
155
|
flexmock(RightScale::Log).should_receive(:info).with("Request type failed (test) and should be retried").once
|
153
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
156
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
154
157
|
and_yield(RightScale::OperationResult.retry('test')).once
|
155
158
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
156
159
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
@@ -161,7 +164,7 @@ describe RightScale::RetryableRequest do
|
|
161
164
|
request = RightScale::RetryableRequest.new('type', 'payload')
|
162
165
|
flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
|
163
166
|
flexmock(RightScale::Log).should_receive(:info).with("Request type failed (RightScale not ready) and should be retried").once
|
164
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
167
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
165
168
|
and_yield(RightScale::OperationResult.retry).once
|
166
169
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
167
170
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
@@ -170,7 +173,7 @@ describe RightScale::RetryableRequest do
|
|
170
173
|
|
171
174
|
it 'should ignore responses that arrive post-cancel' do
|
172
175
|
request = RightScale::RetryableRequest.new('type', 'payload')
|
173
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
176
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
174
177
|
and_yield(RightScale::OperationResult.success('test')).once
|
175
178
|
flexmock(request).should_receive(:fail).once
|
176
179
|
flexmock(request).should_receive(:succeed).never
|
@@ -183,7 +186,7 @@ describe RightScale::RetryableRequest do
|
|
183
186
|
it 'should never retry after cancel response' do
|
184
187
|
request = RightScale::RetryableRequest.new('type', 'payload')
|
185
188
|
flexmock(RightScale::Log).should_receive(:info).with("Request type canceled (enough already)").once
|
186
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
189
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
187
190
|
and_yield(RightScale::OperationResult.cancel('enough already')).once
|
188
191
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
189
192
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).never
|
@@ -195,7 +198,7 @@ describe RightScale::RetryableRequest do
|
|
195
198
|
it 'should control the initial retry delay' do
|
196
199
|
retry_delay = 10
|
197
200
|
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay)
|
198
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
201
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
199
202
|
and_yield(RightScale::OperationResult.retry('test')).once
|
200
203
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
201
204
|
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).once
|
@@ -206,7 +209,7 @@ describe RightScale::RetryableRequest do
|
|
206
209
|
it 'should treat -1 as meaning no delay' do
|
207
210
|
retry_delay = -1
|
208
211
|
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay)
|
209
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
212
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
210
213
|
and_yield(RightScale::OperationResult.retry('test')).once
|
211
214
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
212
215
|
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).never
|
@@ -222,7 +225,7 @@ describe RightScale::RetryableRequest do
|
|
222
225
|
backoff_factor = RightScale::RetryableRequest::RETRY_BACKOFF_FACTOR
|
223
226
|
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay,
|
224
227
|
:retry_delay_count => retry_delay_count)
|
225
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
228
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
226
229
|
and_yield(RightScale::OperationResult.retry('test')).twice
|
227
230
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
228
231
|
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.once
|
@@ -239,7 +242,7 @@ describe RightScale::RetryableRequest do
|
|
239
242
|
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay,
|
240
243
|
:retry_delay_count => retry_delay_count,
|
241
244
|
:max_retry_delay => max_retry_delay)
|
242
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
245
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
243
246
|
and_yield(RightScale::OperationResult.retry('test')).times(4)
|
244
247
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
245
248
|
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.twice
|
@@ -260,7 +263,7 @@ describe RightScale::RetryableRequest do
|
|
260
263
|
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay,
|
261
264
|
:retry_delay_count => retry_delay_count,
|
262
265
|
:max_retry_delay => max_retry_delay)
|
263
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
266
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
|
264
267
|
and_yield(RightScale::OperationResult.retry('test')).times(3)
|
265
268
|
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
266
269
|
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.once
|
@@ -277,7 +280,7 @@ describe RightScale::RetryableRequest do
|
|
277
280
|
context 'when disable timeout' do
|
278
281
|
it 'should not timeout' do
|
279
282
|
request = RightScale::RetryableRequest.new('type', 'payload', :timeout => -1)
|
280
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).once
|
283
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, {}, Proc).once
|
281
284
|
flexmock(EM).should_receive(:add_timer).never
|
282
285
|
request.run
|
283
286
|
end
|
@@ -287,7 +290,8 @@ describe RightScale::RetryableRequest do
|
|
287
290
|
it 'should time the response' do
|
288
291
|
timeout = 10
|
289
292
|
request = RightScale::RetryableRequest.new('type', 'payload', :timeout => timeout)
|
290
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).
|
293
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).
|
294
|
+
with('type', 'payload', nil, {:time_to_live => timeout}, Proc).once
|
291
295
|
flexmock(EM).should_receive(:add_timer).with(timeout, Proc).once
|
292
296
|
request.run
|
293
297
|
end
|
@@ -296,10 +300,21 @@ describe RightScale::RetryableRequest do
|
|
296
300
|
timeout = 10
|
297
301
|
request = RightScale::RetryableRequest.new('type', 'payload', :timeout => timeout)
|
298
302
|
flexmock(RightScale::Log).should_receive(:info).with("Request type timed out after 10 seconds").once
|
299
|
-
flexmock(RightScale::Sender.instance).should_receive(:send_request).
|
303
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).
|
304
|
+
with('type', 'payload', nil, {:time_to_live => timeout}, Proc).once
|
300
305
|
flexmock(EM).should_receive(:add_timer).with(timeout, Proc).and_yield.once
|
301
306
|
request.run
|
302
307
|
end
|
308
|
+
|
309
|
+
it "should cancel request if time has expired" do
|
310
|
+
timeout = 10
|
311
|
+
now = Time.now
|
312
|
+
flexmock(Time).should_receive(:now).and_return(now, now + 10)
|
313
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :timeout => timeout)
|
314
|
+
flexmock(request).should_receive(:fail).once
|
315
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).never
|
316
|
+
request.run
|
317
|
+
end
|
303
318
|
end
|
304
319
|
end
|
305
320
|
|