right_agent 2.1.5-x86-mingw32 → 2.2.0-x86-mingw32
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.
- 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
|
|