right_agent 2.2.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|