right_agent 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -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 +69 -87
- data/lib/right_agent/agent_tag_manager.rb +1 -1
- data/lib/right_agent/clients/api_client.rb +0 -1
- data/lib/right_agent/clients/auth_client.rb +2 -6
- data/lib/right_agent/clients/balanced_http_client.rb +2 -2
- data/lib/right_agent/clients/base_retry_client.rb +12 -19
- data/lib/right_agent/clients/right_http_client.rb +1 -5
- data/lib/right_agent/clients/router_client.rb +8 -15
- data/lib/right_agent/command/command_parser.rb +3 -3
- data/lib/right_agent/command/command_runner.rb +1 -1
- data/lib/right_agent/connectivity_checker.rb +7 -11
- data/lib/right_agent/dispatcher.rb +7 -42
- data/lib/right_agent/enrollment_result.rb +2 -2
- data/lib/right_agent/error_tracker.rb +202 -0
- data/lib/right_agent/log.rb +0 -2
- data/lib/right_agent/packets.rb +1 -1
- data/lib/right_agent/pending_requests.rb +10 -4
- data/lib/right_agent/pid_file.rb +3 -3
- data/lib/right_agent/protocol_version_mixin.rb +3 -3
- data/lib/right_agent/scripts/agent_deployer.rb +13 -1
- data/lib/right_agent/sender.rb +14 -30
- data/lib/right_agent/serialize/secure_serializer.rb +4 -4
- data/right_agent.gemspec +2 -2
- data/spec/agent_spec.rb +5 -5
- data/spec/clients/auth_client_spec.rb +1 -1
- data/spec/clients/balanced_http_client_spec.rb +4 -2
- data/spec/clients/base_retry_client_spec.rb +5 -6
- data/spec/clients/router_client_spec.rb +1 -4
- data/spec/dispatcher_spec.rb +6 -55
- data/spec/error_tracker_spec.rb +293 -0
- data/spec/pending_requests_spec.rb +2 -2
- data/spec/sender_spec.rb +3 -3
- data/spec/spec_helper.rb +4 -2
- metadata +33 -66
@@ -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)
|
@@ -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
|
@@ -178,7 +178,7 @@ module RightScale
|
|
178
178
|
e2 = HttpExceptions.convert(e)
|
179
179
|
log_failure(used[:host], path, params, filter, request_uuid, started_at, e2)
|
180
180
|
raise e2
|
181
|
-
rescue
|
181
|
+
rescue StandardError => e
|
182
182
|
log_failure(used[:host], path, params, filter, request_uuid, started_at, e)
|
183
183
|
raise
|
184
184
|
end
|
@@ -345,7 +345,7 @@ module RightScale
|
|
345
345
|
def log_failure(host, path, params, filter, request_uuid, started_at, exception)
|
346
346
|
code = exception.respond_to?(:http_code) ? exception.http_code : "nil"
|
347
347
|
duration = "%.0fms" % ((Time.now - started_at) * 1000)
|
348
|
-
|
348
|
+
ErrorTracker.log(self, "Failed <#{request_uuid}> in #{duration} | #{code} " + log_text(path, params, filter, host, exception))
|
349
349
|
true
|
350
350
|
end
|
351
351
|
|
@@ -77,7 +77,6 @@ module RightScale
|
|
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
79
|
# whose values are to be hidden when logging; can be augmented on individual requests
|
80
|
-
# @option options [Proc] :exception_callback for unexpected exceptions
|
81
80
|
#
|
82
81
|
# @return [Boolean] whether currently connected
|
83
82
|
#
|
@@ -161,7 +160,6 @@ module RightScale
|
|
161
160
|
# [Hash, NilClass] "request sent" Activity stats or nil if none
|
162
161
|
# [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 }
|
@@ -180,8 +178,7 @@ module RightScale
|
|
180
178
|
"reconnects" => RightSupport::Stats::Activity.new,
|
181
179
|
"request failures" => RightSupport::Stats::Activity.new,
|
182
180
|
"requests sent" => RightSupport::Stats::Activity.new,
|
183
|
-
"state" => RightSupport::Stats::Activity.new
|
184
|
-
"exceptions" => RightSupport::Stats::Exceptions.new(agent = nil, @options[:exception_callback]) }
|
181
|
+
"state" => RightSupport::Stats::Activity.new }
|
185
182
|
true
|
186
183
|
end
|
187
184
|
|
@@ -212,8 +209,7 @@ module RightScale
|
|
212
209
|
begin
|
213
210
|
callback.call(@type, @state)
|
214
211
|
rescue StandardError => e
|
215
|
-
|
216
|
-
@stats["exceptions"].track("status", e)
|
212
|
+
ErrorTracker.log(self, "Failed status callback", e, nil, :caller)
|
217
213
|
end
|
218
214
|
end
|
219
215
|
reconnect if @state == :disconnected
|
@@ -248,9 +244,8 @@ module RightScale
|
|
248
244
|
def close_http_client(reason)
|
249
245
|
@http_client.close(reason) if @http_client
|
250
246
|
true
|
251
|
-
rescue
|
252
|
-
|
253
|
-
@stats["exceptions"].track("status", e)
|
247
|
+
rescue StandardError => e
|
248
|
+
ErrorTracker.log(self, "Failed closing connection", e)
|
254
249
|
false
|
255
250
|
end
|
256
251
|
|
@@ -271,11 +266,10 @@ module RightScale
|
|
271
266
|
@http_client.check_health
|
272
267
|
self.state = :connected
|
273
268
|
rescue BalancedHttpClient::NotResponding => e
|
274
|
-
|
269
|
+
ErrorTracker.log(self, "Failed #{@options[:server_name]} health check", e.nested_exception)
|
275
270
|
self.state = :disconnected
|
276
|
-
rescue
|
277
|
-
|
278
|
-
@stats["exceptions"].track("check health", e)
|
271
|
+
rescue StandardError => e
|
272
|
+
ErrorTracker.log(self, "Failed #{@options[:server_name]} health check", e, nil, :caller)
|
279
273
|
self.state = :disconnected
|
280
274
|
end
|
281
275
|
end
|
@@ -298,9 +292,8 @@ module RightScale
|
|
298
292
|
@reconnect_timer = @reconnecting = nil
|
299
293
|
end
|
300
294
|
rescue Exception => e
|
301
|
-
|
295
|
+
ErrorTracker.log(self, "Failed #{@options[:server_name]} reconnect", e, nil, :caller)
|
302
296
|
@stats["reconnects"].update("failure")
|
303
|
-
@stats["exceptions"].track("reconnect", e)
|
304
297
|
self.state = :disconnected
|
305
298
|
end
|
306
299
|
@reconnect_timer.interval = @options[:reconnect_interval] if @reconnect_timer
|
@@ -472,8 +465,8 @@ module RightScale
|
|
472
465
|
@stats["request failures"].update("#{type} - retry")
|
473
466
|
raise Exceptions::RetryableError.new(retry_result.http_body, retry_result)
|
474
467
|
else
|
475
|
-
|
476
|
-
|
468
|
+
ErrorTracker.log(self, "Retrying #{type} request <#{request_uuid}> in #{interval} seconds " +
|
469
|
+
"in response to retryable error (#{retry_result.http_body})")
|
477
470
|
wait(interval)
|
478
471
|
end
|
479
472
|
# Change request_uuid so that retried request not rejected as duplicate
|
@@ -505,8 +498,8 @@ module RightScale
|
|
505
498
|
self.state = :disconnected
|
506
499
|
raise Exceptions::ConnectivityFailure.new(not_responding.message + " after #{attempts} attempts")
|
507
500
|
else
|
508
|
-
|
509
|
-
|
501
|
+
ErrorTracker.log(self, "Retrying #{type} request <#{request_uuid}> in #{interval} seconds " +
|
502
|
+
"in response to routing failure (#{BalancedHttpClient.exception_text(not_responding)})")
|
510
503
|
wait(interval)
|
511
504
|
end
|
512
505
|
true
|
@@ -51,10 +51,6 @@ module RightScale
|
|
51
51
|
# @option options [Boolean] :long_polling_only never attempt to create a WebSocket, always long-polling instead
|
52
52
|
# @option options [Array] :filter_params symbols or strings for names of request parameters
|
53
53
|
# whose values are to be hidden when logging
|
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
|
58
54
|
#
|
59
55
|
# @return [TrueClass] always true
|
60
56
|
#
|
@@ -275,7 +271,7 @@ module RightScale
|
|
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,6 @@ 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 [Proc] :exception_callback for unexpected exceptions
|
92
91
|
#
|
93
92
|
# @raise [ArgumentError] auth client does not support this client type
|
94
93
|
def initialize(auth_client, options)
|
@@ -262,7 +261,6 @@ module RightScale
|
|
262
261
|
# [Hash, NilClass] "request failures" Activity stats or nil if none
|
263
262
|
# [Hash, NilClass] "request sent" Activity stats or nil if none
|
264
263
|
# [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
264
|
def stats(reset = false)
|
267
265
|
events = @stats["events"].all
|
268
266
|
stats = super(reset)
|
@@ -337,11 +335,10 @@ module RightScale
|
|
337
335
|
end
|
338
336
|
@listen_failures = 0
|
339
337
|
rescue Exception => e
|
340
|
-
|
341
|
-
@stats["exceptions"].track("listen", e)
|
338
|
+
ErrorTracker.log(self, "Failed to listen", e)
|
342
339
|
@listen_failures += 1
|
343
340
|
if @listen_failures > MAX_LISTEN_FAILURES
|
344
|
-
|
341
|
+
ErrorTracker.log(self, "Exceeded maximum repeated listen failures (#{MAX_LISTEN_FAILURES}), stopping listening")
|
345
342
|
@listen_state = :cancel
|
346
343
|
self.state = :failed
|
347
344
|
return false
|
@@ -440,8 +437,7 @@ module RightScale
|
|
440
437
|
connect(routing_keys, &handler)
|
441
438
|
update_listen_state(:check, 1)
|
442
439
|
rescue Exception => e
|
443
|
-
|
444
|
-
@stats["exceptions"].track("websocket", e)
|
440
|
+
ErrorTracker.log(self, "Failed creating WebSocket", e, nil, :caller)
|
445
441
|
backoff_connect_interval
|
446
442
|
update_listen_state(:long_poll)
|
447
443
|
end
|
@@ -477,7 +473,7 @@ module RightScale
|
|
477
473
|
@websocket = Faye::WebSocket::Client.new(url.to_s, protocols = nil, options)
|
478
474
|
|
479
475
|
@websocket.onerror = lambda do |event|
|
480
|
-
|
476
|
+
ErrorTracker.log(self, "WebSocket error (#{event.data})") if event.data
|
481
477
|
end
|
482
478
|
|
483
479
|
@websocket.onclose = lambda do |event|
|
@@ -488,8 +484,7 @@ module RightScale
|
|
488
484
|
msg << ((event.reason.nil? || event.reason.empty?) ? ")" : ": #{event.reason})")
|
489
485
|
Log.info(msg)
|
490
486
|
rescue Exception => e
|
491
|
-
|
492
|
-
@stats["exceptions"].track("event", e)
|
487
|
+
ErrorTracker.log(self, "Failed closing WebSocket", e)
|
493
488
|
end
|
494
489
|
@websocket = nil
|
495
490
|
end
|
@@ -508,8 +503,7 @@ module RightScale
|
|
508
503
|
handler.call(event)
|
509
504
|
@communicated_callbacks.each { |callback| callback.call } if @communicated_callbacks
|
510
505
|
rescue Exception => e
|
511
|
-
|
512
|
-
@stats["exceptions"].track("event", e)
|
506
|
+
ErrorTracker.log(self, "Failed handling WebSocket event", e)
|
513
507
|
end
|
514
508
|
end
|
515
509
|
|
@@ -596,6 +590,7 @@ module RightScale
|
|
596
590
|
end
|
597
591
|
|
598
592
|
# Process result from long-polling attempt
|
593
|
+
# Not necessary to log failure since should already have been done by underlying HTTP client
|
599
594
|
#
|
600
595
|
# @param [Array, NilClass] result from long-polling attempt
|
601
596
|
#
|
@@ -603,12 +598,10 @@ module RightScale
|
|
603
598
|
def process_long_poll(result)
|
604
599
|
case result
|
605
600
|
when Exceptions::Unauthorized, Exceptions::ConnectivityFailure, Exceptions::RetryableError, Exceptions::InternalServerError
|
606
|
-
Log.error("Failed long-polling", result, :no_trace)
|
607
601
|
update_listen_state(:choose, backoff_reconnect_interval)
|
608
602
|
result = nil
|
609
603
|
when Exception
|
610
|
-
|
611
|
-
@stats["exceptions"].track("long-polling", result)
|
604
|
+
ErrorTracker.track(self, result)
|
612
605
|
update_listen_state(:choose, backoff_reconnect_interval)
|
613
606
|
result = nil
|
614
607
|
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
|
|
@@ -38,13 +38,12 @@ module RightScale
|
|
38
38
|
# Timer while waiting for RightNet router ping response
|
39
39
|
attr_accessor :ping_timer
|
40
40
|
|
41
|
-
def initialize(sender, check_interval, ping_stats
|
41
|
+
def initialize(sender, check_interval, ping_stats)
|
42
42
|
@sender = sender
|
43
43
|
@check_interval = check_interval
|
44
44
|
@ping_timeouts = {}
|
45
45
|
@ping_timer = nil
|
46
46
|
@ping_stats = ping_stats
|
47
|
-
@exception_stats = exception_stats
|
48
47
|
@last_received = Time.now
|
49
48
|
@message_received_callbacks = []
|
50
49
|
restart_inactivity_timer if @check_interval > 0
|
@@ -98,17 +97,16 @@ module RightScale
|
|
98
97
|
@ping_timer = nil
|
99
98
|
@ping_timeouts[@ping_id] = (@ping_timeouts[@ping_id] || 0) + 1
|
100
99
|
if @ping_timeouts[@ping_id] >= max_ping_timeouts
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
ErrorTracker.log(self, "Mapper ping via broker #{@ping_id} timed out after #{PING_TIMEOUT} seconds and now " +
|
101
|
+
"reached maximum of #{max_ping_timeouts} timeout#{max_ping_timeouts > 1 ? 's' : ''}, " +
|
102
|
+
"attempting to reconnect")
|
104
103
|
host, port, index, priority = @sender.client.identity_parts(@ping_id)
|
105
104
|
@sender.agent.connect(host, port, index, priority, force = true)
|
106
105
|
else
|
107
106
|
Log.warning("Mapper ping via broker #{@ping_id} timed out after #{PING_TIMEOUT} seconds")
|
108
107
|
end
|
109
108
|
rescue Exception => e
|
110
|
-
|
111
|
-
@exception_stats.track("ping timeout", e)
|
109
|
+
ErrorTracker.log(self, "Failed to reconnect to broker #{@ping_id}", e)
|
112
110
|
end
|
113
111
|
else
|
114
112
|
@ping_timer = nil
|
@@ -125,8 +123,7 @@ module RightScale
|
|
125
123
|
@ping_id = nil
|
126
124
|
end
|
127
125
|
rescue Exception => e
|
128
|
-
|
129
|
-
@exception_stats.track("cancel ping", e)
|
126
|
+
ErrorTracker.log(self, "Failed to cancel router ping", e)
|
130
127
|
end
|
131
128
|
end
|
132
129
|
request = Request.new("/router/ping", nil, {:from => @sender.identity, :token => AgentIdentity.generate})
|
@@ -167,8 +164,7 @@ module RightScale
|
|
167
164
|
begin
|
168
165
|
check(id = nil, max_ping_timeouts = 1)
|
169
166
|
rescue Exception => e
|
170
|
-
|
171
|
-
@exception_stats.track("check connectivity", e)
|
167
|
+
ErrorTracker.log(self, "Failed connectivity check", e)
|
172
168
|
end
|
173
169
|
end
|
174
170
|
true
|
@@ -27,8 +27,8 @@ module RightScale
|
|
27
27
|
|
28
28
|
include ProtocolVersionMixin
|
29
29
|
|
30
|
-
class InvalidRequestType <
|
31
|
-
class DuplicateRequest <
|
30
|
+
class InvalidRequestType < RuntimeError; end
|
31
|
+
class DuplicateRequest < RuntimeError; end
|
32
32
|
|
33
33
|
# (ActorRegistry) Registry for actors
|
34
34
|
attr_reader :registry
|
@@ -88,7 +88,7 @@ module RightScale
|
|
88
88
|
actor, method, idempotent = route(request)
|
89
89
|
received_at = @request_stats.update(method, (token if request.is_a?(Request)))
|
90
90
|
if (dup = duplicate?(request, method, idempotent))
|
91
|
-
raise DuplicateRequest
|
91
|
+
raise DuplicateRequest, dup
|
92
92
|
end
|
93
93
|
unless (result = expired?(request, method))
|
94
94
|
result = perform(request, actor, method, idempotent)
|
@@ -110,9 +110,6 @@ module RightScale
|
|
110
110
|
# or nil if empty
|
111
111
|
# "dispatch failures"(Hash|nil):: Dispatch failure activity stats with keys "total", "percent", "last", and "rate"
|
112
112
|
# with percentage breakdown per failure type, or nil if none
|
113
|
-
# "exceptions"(Hash|nil):: Exceptions raised per category, or nil if none
|
114
|
-
# "total"(Integer):: Total for category
|
115
|
-
# "recent"(Array):: Most recent as a hash of "count", "type", "message", "when", and "where"
|
116
113
|
# "rejects"(Hash|nil):: Request reject activity stats with keys "total", "percent", "last", and "rate"
|
117
114
|
# with percentage breakdown per reason ("duplicate (<method>)", "retry duplicate (<method>)", or
|
118
115
|
# "stale (<method>)"), or nil if none
|
@@ -123,7 +120,6 @@ module RightScale
|
|
123
120
|
stats = {
|
124
121
|
"dispatched cache" => (@dispatched_cache.stats if @dispatched_cache),
|
125
122
|
"dispatch failures" => @dispatch_failure_stats.all,
|
126
|
-
"exceptions" => @exception_stats.stats,
|
127
123
|
"rejects" => @reject_stats.all,
|
128
124
|
"requests" => @request_stats.all,
|
129
125
|
"response time" => @request_stats.avg_duration
|
@@ -142,7 +138,6 @@ module RightScale
|
|
142
138
|
@reject_stats = RightSupport::Stats::Activity.new
|
143
139
|
@request_stats = RightSupport::Stats::Activity.new
|
144
140
|
@dispatch_failure_stats = RightSupport::Stats::Activity.new
|
145
|
-
@exception_stats = RightSupport::Stats::Exceptions.new(@agent, @agent.exception_callback)
|
146
141
|
true
|
147
142
|
end
|
148
143
|
|
@@ -209,7 +204,7 @@ module RightScale
|
|
209
204
|
method = method.to_sym
|
210
205
|
actor = @registry.actor_for(prefix)
|
211
206
|
if actor.nil? || !actor.respond_to?(method)
|
212
|
-
raise InvalidRequestType
|
207
|
+
raise InvalidRequestType, "Unknown actor or method for dispatching request <#{request.token}> of type #{request.type}"
|
213
208
|
end
|
214
209
|
[actor, method, actor.class.idempotent?(method)]
|
215
210
|
end
|
@@ -231,40 +226,10 @@ module RightScale
|
|
231
226
|
else
|
232
227
|
actor.send(method, request.payload, request)
|
233
228
|
end
|
234
|
-
rescue
|
229
|
+
rescue StandardError => e
|
230
|
+
ErrorTracker.log(self, "Failed dispatching #{request.trace}", e, request)
|
235
231
|
@dispatch_failure_stats.update("#{request.type}->#{e.class.name}")
|
236
|
-
OperationResult.error(
|
237
|
-
end
|
238
|
-
|
239
|
-
# Handle exception by logging it, calling the actors exception callback method,
|
240
|
-
# and gathering exception statistics
|
241
|
-
#
|
242
|
-
# === Parameters
|
243
|
-
# actor(Actor):: Actor that failed to process request
|
244
|
-
# method(Symbol):: Name of actor method being dispatched to
|
245
|
-
# request(Packet):: Packet that dispatcher is acting upon
|
246
|
-
# exception(Exception):: Exception that was raised
|
247
|
-
#
|
248
|
-
# === Return
|
249
|
-
# (String):: Error description for this exception
|
250
|
-
def handle_exception(actor, method, request, exception)
|
251
|
-
error = "Could not handle #{request.type} request"
|
252
|
-
Log.error(error, exception, :trace)
|
253
|
-
begin
|
254
|
-
if actor && actor.class.exception_callback
|
255
|
-
case actor.class.exception_callback
|
256
|
-
when Symbol, String
|
257
|
-
actor.send(actor.class.exception_callback, method, request, exception)
|
258
|
-
when Proc
|
259
|
-
actor.instance_exec(method, request, exception, &actor.class.exception_callback)
|
260
|
-
end
|
261
|
-
end
|
262
|
-
@exception_stats.track(request.type, exception)
|
263
|
-
rescue Exception => e
|
264
|
-
Log.error("Failed handling error for #{request.type}", e, :trace)
|
265
|
-
@exception_stats.track(request.type, e) rescue nil
|
266
|
-
end
|
267
|
-
Log.format(error, exception)
|
232
|
+
OperationResult.error("Could not handle #{request.type} request", e)
|
268
233
|
end
|
269
234
|
|
270
235
|
end # Dispatcher
|