right_agent 2.2.1-x86-mingw32 → 2.4.3-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -0
- data/lib/right_agent.rb +1 -0
- data/lib/right_agent/actor.rb +0 -28
- data/lib/right_agent/actors/agent_manager.rb +20 -18
- data/lib/right_agent/agent.rb +70 -87
- data/lib/right_agent/agent_config.rb +1 -1
- data/lib/right_agent/agent_tag_manager.rb +1 -1
- data/lib/right_agent/clients/api_client.rb +2 -1
- data/lib/right_agent/clients/auth_client.rb +2 -6
- data/lib/right_agent/clients/balanced_http_client.rb +22 -11
- data/lib/right_agent/clients/base_retry_client.rb +14 -22
- data/lib/right_agent/clients/non_blocking_client.rb +1 -0
- data/lib/right_agent/clients/right_http_client.rb +4 -8
- data/lib/right_agent/clients/router_client.rb +10 -16
- data/lib/right_agent/command/command_parser.rb +3 -3
- data/lib/right_agent/command/command_runner.rb +1 -1
- data/lib/right_agent/command/command_serializer.rb +0 -32
- data/lib/right_agent/connectivity_checker.rb +7 -11
- data/lib/right_agent/core_payload_types/dev_repository.rb +32 -0
- data/lib/right_agent/dispatcher.rb +8 -45
- data/lib/right_agent/enrollment_result.rb +2 -2
- data/lib/right_agent/error_tracker.rb +230 -0
- data/lib/right_agent/exceptions.rb +1 -1
- data/lib/right_agent/log.rb +8 -6
- data/lib/right_agent/packets.rb +5 -3
- data/lib/right_agent/pending_requests.rb +10 -4
- data/lib/right_agent/pid_file.rb +3 -3
- data/lib/right_agent/platform.rb +14 -14
- data/lib/right_agent/protocol_version_mixin.rb +6 -3
- data/lib/right_agent/scripts/agent_deployer.rb +13 -1
- data/lib/right_agent/sender.rb +16 -35
- data/lib/right_agent/serialize/secure_serializer.rb +6 -9
- data/lib/right_agent/serialize/serializer.rb +7 -3
- data/right_agent.gemspec +5 -5
- data/spec/agent_spec.rb +5 -5
- data/spec/clients/auth_client_spec.rb +1 -1
- data/spec/clients/balanced_http_client_spec.rb +20 -28
- data/spec/clients/base_retry_client_spec.rb +5 -6
- data/spec/clients/non_blocking_client_spec.rb +4 -0
- data/spec/clients/router_client_spec.rb +1 -4
- data/spec/dispatcher_spec.rb +6 -55
- data/spec/error_tracker_spec.rb +346 -0
- data/spec/log_spec.rb +4 -0
- data/spec/pending_requests_spec.rb +2 -2
- data/spec/sender_spec.rb +3 -3
- data/spec/serialize/serializer_spec.rb +14 -0
- data/spec/spec_helper.rb +4 -2
- metadata +13 -11
@@ -185,7 +185,7 @@ module RightScale
|
|
185
185
|
request = RightScale::RetryableRequest.new("/router/query_tags", payload, request_options)
|
186
186
|
request.callback { |result| yield raw ? request.raw_response : result }
|
187
187
|
request.errback do |message|
|
188
|
-
|
188
|
+
ErrorTracker.log(self, "Failed to query tags (#{message})")
|
189
189
|
yield((raw ? request.raw_response : nil) || message)
|
190
190
|
end
|
191
191
|
request.run
|
@@ -83,7 +83,6 @@ module RightScale
|
|
83
83
|
# @option options [Array] :retry_intervals between successive retries; defaults to DEFAULT_RETRY_INTERVALS
|
84
84
|
# @option options [Boolean] :retry_enabled for requests that fail to connect or that return a retry result
|
85
85
|
# @option options [Numeric] :reconnect_interval for reconnect attempts after lose connectivity
|
86
|
-
# @option options [Proc] :exception_callback for unexpected exceptions
|
87
86
|
#
|
88
87
|
# @raise [ArgumentError] auth client does not support this client type
|
89
88
|
def initialize(auth_client, options)
|
@@ -102,6 +101,7 @@ module RightScale
|
|
102
101
|
# @param [String, Hash, NilClass] target for request, which may be identity of specific
|
103
102
|
# target, hash for selecting potentially multiple targets, or nil if routing solely
|
104
103
|
# using type; hash may contain:
|
104
|
+
# [String] :agent_id serialized identity of specific target
|
105
105
|
# [Array] :tags that must all be associated with a target for it to be selected
|
106
106
|
# [Hash] :scope for restricting routing which may contain:
|
107
107
|
# [Integer] :account id that agents must be associated with to be included
|
@@ -140,6 +140,7 @@ module RightScale
|
|
140
140
|
# @param [String, Hash, NilClass] target for request, which may be identity of specific
|
141
141
|
# target, hash for selecting targets of which one is picked randomly, or nil if routing solely
|
142
142
|
# using type; hash may contain:
|
143
|
+
# [String] :agent_id serialized identity of specific target
|
143
144
|
# [Array] :tags that must all be associated with a target for it to be selected
|
144
145
|
# [Hash] :scope for restricting routing which may contain:
|
145
146
|
# [Integer] :account id that agents must be associated with to be included
|
@@ -175,7 +175,6 @@ module RightScale
|
|
175
175
|
#
|
176
176
|
# @return [Hash] current statistics
|
177
177
|
# [Hash, NilClass] "state" Activity stats or nil if none
|
178
|
-
# [Hash, NilClass] "exceptions" Exceptions stats or nil if none
|
179
178
|
def stats(reset = false)
|
180
179
|
stats = {}
|
181
180
|
@stats.each { |k, v| stats[k] = v.all }
|
@@ -189,9 +188,7 @@ module RightScale
|
|
189
188
|
#
|
190
189
|
# @return [TrueClass] always true
|
191
190
|
def reset_stats
|
192
|
-
@stats = {
|
193
|
-
"state" => RightSupport::Stats::Activity.new,
|
194
|
-
"exceptions" => RightSupport::Stats::Exceptions.new(agent = nil, @exception_callback)}
|
191
|
+
@stats = {"state" => RightSupport::Stats::Activity.new}
|
195
192
|
true
|
196
193
|
end
|
197
194
|
|
@@ -246,8 +243,7 @@ module RightScale
|
|
246
243
|
begin
|
247
244
|
callback.call(:auth, @state)
|
248
245
|
rescue StandardError => e
|
249
|
-
|
250
|
-
@stats["exceptions"].track("status", e)
|
246
|
+
ErrorTracker.log(self, "Failed status callback", e, nil, :caller)
|
251
247
|
end
|
252
248
|
end
|
253
249
|
end
|
@@ -59,6 +59,9 @@ module RightScale
|
|
59
59
|
# Text used for filtered parameter value
|
60
60
|
FILTERED_PARAM_VALUE = "<hidden>"
|
61
61
|
|
62
|
+
# Parameters whose contents are also to have filtering applied
|
63
|
+
CONTENT_FILTERED_PARAMS = ["payload"]
|
64
|
+
|
62
65
|
# Environment variables to examine for proxy settings, in order
|
63
66
|
PROXY_ENVIRONMENT_VARIABLES = ['HTTPS_PROXY', 'https_proxy', 'HTTP_PROXY', 'http_proxy', 'ALL_PROXY']
|
64
67
|
|
@@ -71,7 +74,8 @@ module RightScale
|
|
71
74
|
# @option options [String] :health_check_path in URI for health check resource;
|
72
75
|
# defaults to DEFAULT_HEALTH_CHECK_PATH
|
73
76
|
# @option options [Array] :filter_params symbols or strings for names of request parameters
|
74
|
-
# whose values are to be hidden when logging;
|
77
|
+
# whose values are to be hidden when logging; also applied to contents of any parameters
|
78
|
+
# in CONTENT_FILTERED_PARAMS; can be augmented on individual requests
|
75
79
|
# @option options [Boolean] :non_blocking i/o is to be used for HTTP requests by applying
|
76
80
|
# EM::HttpRequest and fibers instead of RestClient; requests remain synchronous
|
77
81
|
def initialize(urls, options = {})
|
@@ -140,9 +144,9 @@ module RightScale
|
|
140
144
|
# @option options [Numeric] :open_timeout maximum wait for connection; defaults to DEFAULT_OPEN_TIMEOUT
|
141
145
|
# @option options [Numeric] :request_timeout maximum wait for response; defaults to DEFAULT_REQUEST_TIMEOUT
|
142
146
|
# @option options [String] :request_uuid uniquely identifying request; defaults to random generated UUID
|
143
|
-
# @option options [Array] :filter_params symbols or strings for names of request
|
144
|
-
#
|
145
|
-
#
|
147
|
+
# @option options [Array] :filter_params symbols or strings for names of request parameters whose
|
148
|
+
# values are to be hidden when logging in addition to the ones provided during object initialization;
|
149
|
+
# also applied to contents of any parameters named :payload
|
146
150
|
# @option options [Hash] :headers to be added to request
|
147
151
|
# @option options [Numeric] :poll_timeout maximum wait for individual poll; defaults to :request_timeout
|
148
152
|
# @option options [Symbol] :log_level to use when logging information about the request other than errors;
|
@@ -178,7 +182,7 @@ module RightScale
|
|
178
182
|
e2 = HttpExceptions.convert(e)
|
179
183
|
log_failure(used[:host], path, params, filter, request_uuid, started_at, e2)
|
180
184
|
raise e2
|
181
|
-
rescue
|
185
|
+
rescue StandardError => e
|
182
186
|
log_failure(used[:host], path, params, filter, request_uuid, started_at, e)
|
183
187
|
raise
|
184
188
|
end
|
@@ -345,7 +349,7 @@ module RightScale
|
|
345
349
|
def log_failure(host, path, params, filter, request_uuid, started_at, exception)
|
346
350
|
code = exception.respond_to?(:http_code) ? exception.http_code : "nil"
|
347
351
|
duration = "%.0fms" % ((Time.now - started_at) * 1000)
|
348
|
-
|
352
|
+
ErrorTracker.log(self, "Failed <#{request_uuid}> in #{duration} | #{code} " + log_text(path, params, filter, host, exception))
|
349
353
|
true
|
350
354
|
end
|
351
355
|
|
@@ -359,8 +363,7 @@ module RightScale
|
|
359
363
|
#
|
360
364
|
# @return [String] Log text
|
361
365
|
def log_text(path, params, filter, host = nil, exception = nil)
|
362
|
-
|
363
|
-
text = filtered_params ? "#{path} #{filtered_params}" : path
|
366
|
+
text = "#{path} #{filter(params, filter).inspect}"
|
364
367
|
text = "[#{host}#{text}]" if host
|
365
368
|
text << " | #{self.class.exception_text(exception)}" if exception
|
366
369
|
text
|
@@ -368,8 +371,9 @@ module RightScale
|
|
368
371
|
|
369
372
|
# Apply parameter hiding filter
|
370
373
|
#
|
371
|
-
# @param [Hash, Object] params to be filtered
|
372
|
-
# @param [Array] filter names of params as strings (not symbols) whose value is to be hidden
|
374
|
+
# @param [Hash, Object] params to be filtered with strings or symbols as keys
|
375
|
+
# @param [Array] filter names of params as strings (not symbols) whose value is to be hidden;
|
376
|
+
# also filter the contents of any CONTENT_FILTERED_PARAMS
|
373
377
|
#
|
374
378
|
# @return [Hash] filtered parameters
|
375
379
|
def filter(params, filter)
|
@@ -377,7 +381,14 @@ module RightScale
|
|
377
381
|
params
|
378
382
|
else
|
379
383
|
filtered_params = {}
|
380
|
-
params.each
|
384
|
+
params.each do |k, p|
|
385
|
+
s = k.to_s
|
386
|
+
if filter.include?(s)
|
387
|
+
filtered_params[k] = FILTERED_PARAM_VALUE
|
388
|
+
else
|
389
|
+
filtered_params[k] = CONTENT_FILTERED_PARAMS.include?(s) ? filter(p, filter) : p
|
390
|
+
end
|
391
|
+
end
|
381
392
|
filtered_params
|
382
393
|
end
|
383
394
|
end
|
@@ -76,8 +76,8 @@ module RightScale
|
|
76
76
|
# @option options [Boolean] :non_blocking i/o is to be used for HTTP requests by applying
|
77
77
|
# EM::HttpRequest and fibers instead of RestClient; requests remain synchronous
|
78
78
|
# @option options [Array] :filter_params symbols or strings for names of request parameters
|
79
|
-
# whose values are to be hidden when logging;
|
80
|
-
#
|
79
|
+
# whose values are to be hidden when logging; also applied to contents of any parameters
|
80
|
+
# named :payload; can be augmented on individual requests
|
81
81
|
#
|
82
82
|
# @return [Boolean] whether currently connected
|
83
83
|
#
|
@@ -159,13 +159,10 @@ module RightScale
|
|
159
159
|
# [Hash, NilClass] "reconnects" Activity stats or nil if none
|
160
160
|
# [Hash, NilClass] "request failures" Activity stats or nil if none
|
161
161
|
# [Hash, NilClass] "request sent" Activity stats or nil if none
|
162
|
-
# [Float, NilClass] "response time" average number of seconds to respond to a request or nil if none
|
163
162
|
# [Hash, NilClass] "state" Activity stats or nil if none
|
164
|
-
# [Hash, NilClass] "exceptions" Exceptions stats or nil if none
|
165
163
|
def stats(reset = false)
|
166
164
|
stats = {}
|
167
165
|
@stats.each { |k, v| stats[k] = v.all }
|
168
|
-
stats["response time"] = @stats["requests sent"].avg_duration
|
169
166
|
reset_stats if reset
|
170
167
|
stats
|
171
168
|
end
|
@@ -180,8 +177,7 @@ module RightScale
|
|
180
177
|
"reconnects" => RightSupport::Stats::Activity.new,
|
181
178
|
"request failures" => RightSupport::Stats::Activity.new,
|
182
179
|
"requests sent" => RightSupport::Stats::Activity.new,
|
183
|
-
"state" => RightSupport::Stats::Activity.new
|
184
|
-
"exceptions" => RightSupport::Stats::Exceptions.new(agent = nil, @options[:exception_callback]) }
|
180
|
+
"state" => RightSupport::Stats::Activity.new }
|
185
181
|
true
|
186
182
|
end
|
187
183
|
|
@@ -212,8 +208,7 @@ module RightScale
|
|
212
208
|
begin
|
213
209
|
callback.call(@type, @state)
|
214
210
|
rescue StandardError => e
|
215
|
-
|
216
|
-
@stats["exceptions"].track("status", e)
|
211
|
+
ErrorTracker.log(self, "Failed status callback", e, nil, :caller)
|
217
212
|
end
|
218
213
|
end
|
219
214
|
reconnect if @state == :disconnected
|
@@ -248,9 +243,8 @@ module RightScale
|
|
248
243
|
def close_http_client(reason)
|
249
244
|
@http_client.close(reason) if @http_client
|
250
245
|
true
|
251
|
-
rescue
|
252
|
-
|
253
|
-
@stats["exceptions"].track("status", e)
|
246
|
+
rescue StandardError => e
|
247
|
+
ErrorTracker.log(self, "Failed closing connection", e)
|
254
248
|
false
|
255
249
|
end
|
256
250
|
|
@@ -271,11 +265,10 @@ module RightScale
|
|
271
265
|
@http_client.check_health
|
272
266
|
self.state = :connected
|
273
267
|
rescue BalancedHttpClient::NotResponding => e
|
274
|
-
|
268
|
+
ErrorTracker.log(self, "Failed #{@options[:server_name]} health check", e.nested_exception)
|
275
269
|
self.state = :disconnected
|
276
|
-
rescue
|
277
|
-
|
278
|
-
@stats["exceptions"].track("check health", e)
|
270
|
+
rescue StandardError => e
|
271
|
+
ErrorTracker.log(self, "Failed #{@options[:server_name]} health check", e, nil, :caller)
|
279
272
|
self.state = :disconnected
|
280
273
|
end
|
281
274
|
end
|
@@ -298,9 +291,8 @@ module RightScale
|
|
298
291
|
@reconnect_timer = @reconnecting = nil
|
299
292
|
end
|
300
293
|
rescue Exception => e
|
301
|
-
|
294
|
+
ErrorTracker.log(self, "Failed #{@options[:server_name]} reconnect", e, nil, :caller)
|
302
295
|
@stats["reconnects"].update("failure")
|
303
|
-
@stats["exceptions"].track("reconnect", e)
|
304
296
|
self.state = :disconnected
|
305
297
|
end
|
306
298
|
@reconnect_timer.interval = @options[:reconnect_interval] if @reconnect_timer
|
@@ -472,8 +464,8 @@ module RightScale
|
|
472
464
|
@stats["request failures"].update("#{type} - retry")
|
473
465
|
raise Exceptions::RetryableError.new(retry_result.http_body, retry_result)
|
474
466
|
else
|
475
|
-
|
476
|
-
|
467
|
+
ErrorTracker.log(self, "Retrying #{type} request <#{request_uuid}> in #{interval} seconds " +
|
468
|
+
"in response to retryable error (#{retry_result.http_body})")
|
477
469
|
wait(interval)
|
478
470
|
end
|
479
471
|
# Change request_uuid so that retried request not rejected as duplicate
|
@@ -505,8 +497,8 @@ module RightScale
|
|
505
497
|
self.state = :disconnected
|
506
498
|
raise Exceptions::ConnectivityFailure.new(not_responding.message + " after #{attempts} attempts")
|
507
499
|
else
|
508
|
-
|
509
|
-
|
500
|
+
ErrorTracker.log(self, "Retrying #{type} request <#{request_uuid}> in #{interval} seconds " +
|
501
|
+
"in response to routing failure (#{BalancedHttpClient.exception_text(not_responding)})")
|
510
502
|
wait(interval)
|
511
503
|
end
|
512
504
|
true
|
@@ -205,6 +205,7 @@ module RightScale
|
|
205
205
|
case error.to_s
|
206
206
|
when "terminating", "reconnecting" then [200, nil]
|
207
207
|
when "Errno::ETIMEDOUT" then [408, "Request timeout"]
|
208
|
+
when "Errno::ECONNREFUSED" then [503, "Connection refused"]
|
208
209
|
else [500, (error && error.to_s) || "HTTP connection failure for #{verb.to_s.upcase}"]
|
209
210
|
end
|
210
211
|
end
|
@@ -49,12 +49,8 @@ module RightScale
|
|
49
49
|
# @option options [Boolean] :non_blocking i/o is to be used for HTTP requests by applying
|
50
50
|
# EM::HttpRequest and fibers instead of RestClient; requests remain synchronous
|
51
51
|
# @option options [Boolean] :long_polling_only never attempt to create a WebSocket, always long-polling instead
|
52
|
-
# @option options [Array] :filter_params symbols or strings for names of request parameters
|
53
|
-
#
|
54
|
-
# @option options [Proc] :exception_callback for unexpected exceptions with following parameters:
|
55
|
-
# [Exception] exception raised
|
56
|
-
# [Packet, NilClass] packet being processed
|
57
|
-
# [Agent, NilClass] agent in which exception occurred
|
52
|
+
# @option options [Array] :filter_params symbols or strings for names of request parameters whose
|
53
|
+
# values are to be hidden when logging; also applied to contents of any parameters named :payload
|
58
54
|
#
|
59
55
|
# @return [TrueClass] always true
|
60
56
|
#
|
@@ -271,11 +267,11 @@ module RightScale
|
|
271
267
|
# @return [Hash] status of various clients
|
272
268
|
def update_status(type, state)
|
273
269
|
@status[type] = state
|
274
|
-
@status_callbacks.each do |callback|
|
270
|
+
(@status_callbacks || []).each do |callback|
|
275
271
|
begin
|
276
272
|
callback.call(type, state)
|
277
273
|
rescue RuntimeError => e
|
278
|
-
|
274
|
+
ErrorTracker.log(self, "Failed status callback", e, nil, :caller)
|
279
275
|
end
|
280
276
|
end
|
281
277
|
@status
|
@@ -88,7 +88,8 @@ module RightScale
|
|
88
88
|
# @option options [Numeric] :reconnect_interval for reconnect attempts after lose connectivity
|
89
89
|
# @option options [Boolean] :non_blocking i/o is to be used for HTTP requests by applying
|
90
90
|
# EM::HttpRequest and fibers instead of RestClient; requests remain synchronous
|
91
|
-
# @option options [
|
91
|
+
# @option options [Array] :filter_params symbols or strings for names of request parameters whose
|
92
|
+
# values are to be hidden when logging; also applied to contents of any parameters named :payload
|
92
93
|
#
|
93
94
|
# @raise [ArgumentError] auth client does not support this client type
|
94
95
|
def initialize(auth_client, options)
|
@@ -261,8 +262,6 @@ module RightScale
|
|
261
262
|
# [Hash, NilClass] "reconnects" Activity stats or nil if none
|
262
263
|
# [Hash, NilClass] "request failures" Activity stats or nil if none
|
263
264
|
# [Hash, NilClass] "request sent" Activity stats or nil if none
|
264
|
-
# [Float, NilClass] "response time" average number of seconds to respond to a request or nil if none
|
265
|
-
# [Hash, NilClass] "exceptions" Exceptions stats or nil if none
|
266
265
|
def stats(reset = false)
|
267
266
|
events = @stats["events"].all
|
268
267
|
stats = super(reset)
|
@@ -337,11 +336,10 @@ module RightScale
|
|
337
336
|
end
|
338
337
|
@listen_failures = 0
|
339
338
|
rescue Exception => e
|
340
|
-
|
341
|
-
@stats["exceptions"].track("listen", e)
|
339
|
+
ErrorTracker.log(self, "Failed to listen", e)
|
342
340
|
@listen_failures += 1
|
343
341
|
if @listen_failures > MAX_LISTEN_FAILURES
|
344
|
-
|
342
|
+
ErrorTracker.log(self, "Exceeded maximum repeated listen failures (#{MAX_LISTEN_FAILURES}), stopping listening")
|
345
343
|
@listen_state = :cancel
|
346
344
|
self.state = :failed
|
347
345
|
return false
|
@@ -440,8 +438,7 @@ module RightScale
|
|
440
438
|
connect(routing_keys, &handler)
|
441
439
|
update_listen_state(:check, 1)
|
442
440
|
rescue Exception => e
|
443
|
-
|
444
|
-
@stats["exceptions"].track("websocket", e)
|
441
|
+
ErrorTracker.log(self, "Failed creating WebSocket", e, nil, :caller)
|
445
442
|
backoff_connect_interval
|
446
443
|
update_listen_state(:long_poll)
|
447
444
|
end
|
@@ -477,7 +474,7 @@ module RightScale
|
|
477
474
|
@websocket = Faye::WebSocket::Client.new(url.to_s, protocols = nil, options)
|
478
475
|
|
479
476
|
@websocket.onerror = lambda do |event|
|
480
|
-
|
477
|
+
ErrorTracker.log(self, "WebSocket error (#{event.data})") if event.data
|
481
478
|
end
|
482
479
|
|
483
480
|
@websocket.onclose = lambda do |event|
|
@@ -488,8 +485,7 @@ module RightScale
|
|
488
485
|
msg << ((event.reason.nil? || event.reason.empty?) ? ")" : ": #{event.reason})")
|
489
486
|
Log.info(msg)
|
490
487
|
rescue Exception => e
|
491
|
-
|
492
|
-
@stats["exceptions"].track("event", e)
|
488
|
+
ErrorTracker.log(self, "Failed closing WebSocket", e)
|
493
489
|
end
|
494
490
|
@websocket = nil
|
495
491
|
end
|
@@ -508,8 +504,7 @@ module RightScale
|
|
508
504
|
handler.call(event)
|
509
505
|
@communicated_callbacks.each { |callback| callback.call } if @communicated_callbacks
|
510
506
|
rescue Exception => e
|
511
|
-
|
512
|
-
@stats["exceptions"].track("event", e)
|
507
|
+
ErrorTracker.log(self, "Failed handling WebSocket event", e)
|
513
508
|
end
|
514
509
|
end
|
515
510
|
|
@@ -596,6 +591,7 @@ module RightScale
|
|
596
591
|
end
|
597
592
|
|
598
593
|
# Process result from long-polling attempt
|
594
|
+
# Not necessary to log failure since should already have been done by underlying HTTP client
|
599
595
|
#
|
600
596
|
# @param [Array, NilClass] result from long-polling attempt
|
601
597
|
#
|
@@ -603,12 +599,10 @@ module RightScale
|
|
603
599
|
def process_long_poll(result)
|
604
600
|
case result
|
605
601
|
when Exceptions::Unauthorized, Exceptions::ConnectivityFailure, Exceptions::RetryableError, Exceptions::InternalServerError
|
606
|
-
Log.error("Failed long-polling", result, :no_trace)
|
607
602
|
update_listen_state(:choose, backoff_reconnect_interval)
|
608
603
|
result = nil
|
609
604
|
when Exception
|
610
|
-
|
611
|
-
@stats["exceptions"].track("long-polling", result)
|
605
|
+
ErrorTracker.track(self, result)
|
612
606
|
update_listen_state(:choose, backoff_reconnect_interval)
|
613
607
|
result = nil
|
614
608
|
else
|
@@ -51,12 +51,12 @@ module RightScale
|
|
51
51
|
def parse_chunk(chunk)
|
52
52
|
@buildup << chunk
|
53
53
|
chunks = @buildup.split(CommandSerializer::SEPARATOR, -1)
|
54
|
-
if do_call = chunks.size > 1
|
54
|
+
if (do_call = chunks.size > 1)
|
55
55
|
commands = []
|
56
56
|
(0..chunks.size - 2).each do |i|
|
57
57
|
begin
|
58
58
|
commands << CommandSerializer.load(chunks[i])
|
59
|
-
rescue
|
59
|
+
rescue StandardError => e
|
60
60
|
# log any exceptions caused by serializing individual chunks instead
|
61
61
|
# of halting EM. each command is discrete so we need to keep trying
|
62
62
|
# so long as there are more commands to process (although subsequent
|
@@ -77,7 +77,7 @@ module RightScale
|
|
77
77
|
@buildup = chunks.last
|
78
78
|
end
|
79
79
|
do_call
|
80
|
-
rescue
|
80
|
+
rescue StandardError => e
|
81
81
|
# log any other exceptions instead of halting EM.
|
82
82
|
Log.error("Failed parsing command chunk", e, :trace)
|
83
83
|
end
|
@@ -79,7 +79,7 @@ module RightScale
|
|
79
79
|
Log.error("Invalid cookie used by command protocol client (#{cmd_cookie})")
|
80
80
|
end
|
81
81
|
rescue Exception => e
|
82
|
-
Log.
|
82
|
+
Log.error("Command failed", e, :trace)
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -37,12 +37,6 @@ module RightScale
|
|
37
37
|
# === Return
|
38
38
|
# data(String):: Corresponding serialized data
|
39
39
|
def self.dump(command)
|
40
|
-
# Set the encoding before serialization otherwise YAML will serialize
|
41
|
-
# UTF8 characters as binary data. This can cause some quirks we'd rather
|
42
|
-
# avoid, such as the deserialized binary data having no encoding on
|
43
|
-
# deserialization
|
44
|
-
set_encoding(command)
|
45
|
-
|
46
40
|
data = YAML::dump(command)
|
47
41
|
data += SEPARATOR
|
48
42
|
end
|
@@ -58,10 +52,6 @@ module RightScale
|
|
58
52
|
# === Raise
|
59
53
|
# (RightScale::Exceptions::IO): If serialized data is incorrect
|
60
54
|
def self.load(data)
|
61
|
-
# Data coming from eventmachine is cleaned of it's encoding, so set it
|
62
|
-
# to UTF-8 manually before deserializing or you'll throw transcode errors.
|
63
|
-
set_encoding(data)
|
64
|
-
|
65
55
|
command = YAML::load(data)
|
66
56
|
|
67
57
|
raise RightScale::Exceptions::IO, "Invalid serialized command:\n#{data}" unless command
|
@@ -72,27 +62,5 @@ module RightScale
|
|
72
62
|
raise RightScale::Exceptions::IO, "Invalid serialized command: #{e.message}\n#{data}"
|
73
63
|
end
|
74
64
|
|
75
|
-
private
|
76
|
-
# Force set encodings on ruby strings.
|
77
|
-
#
|
78
|
-
# === Parameters
|
79
|
-
# obj(Object):: String, or Hash/Array of Strings
|
80
|
-
#
|
81
|
-
# === Return
|
82
|
-
# (nil):: Returns nothing, edits object in place
|
83
|
-
def self.set_encoding(obj, encoding = "UTF-8")
|
84
|
-
if obj.is_a?(Hash)
|
85
|
-
obj.each do |k,v|
|
86
|
-
set_encoding(v, encoding)
|
87
|
-
end
|
88
|
-
elsif obj.is_a?(Array)
|
89
|
-
obj.each do |v|
|
90
|
-
set_encoding(v, encoding)
|
91
|
-
end
|
92
|
-
elsif obj.is_a?(String) && !obj.frozen?
|
93
|
-
obj.force_encoding(encoding) if obj.respond_to?(:force_encoding)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
65
|
end
|
98
66
|
end
|