right_agent 0.5.1 → 0.5.10
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.rb +3 -13
- data/lib/right_agent/actors/agent_manager.rb +78 -4
- data/lib/right_agent/agent.rb +81 -4
- data/lib/right_agent/agent_config.rb +17 -1
- data/lib/right_agent/agent_tags_manager.rb +2 -2
- data/lib/right_agent/broker_client.rb +32 -34
- data/lib/right_agent/command/agent_manager_commands.rb +16 -0
- data/lib/right_agent/command/command_constants.rb +0 -9
- data/lib/right_agent/dispatcher.rb +6 -3
- data/lib/right_agent/ha_broker_client.rb +63 -14
- data/lib/right_agent/log.rb +1 -1
- data/lib/right_agent/minimal.rb +43 -0
- data/lib/right_agent/monkey_patches/amqp_patch.rb +91 -182
- data/lib/right_agent/packets.rb +10 -5
- data/lib/right_agent/platform.rb +8 -0
- data/lib/right_agent/platform/darwin.rb +14 -0
- data/lib/right_agent/platform/linux.rb +23 -0
- data/lib/right_agent/platform/windows.rb +31 -0
- data/lib/right_agent/scripts/agent_controller.rb +16 -8
- data/lib/right_agent/scripts/agent_deployer.rb +6 -0
- data/lib/right_agent/scripts/log_level_manager.rb +4 -5
- data/lib/right_agent/scripts/stats_manager.rb +9 -1
- data/lib/right_agent/sender.rb +623 -371
- data/lib/right_agent/stats_helper.rb +15 -1
- data/lib/right_agent/tracer.rb +1 -1
- data/right_agent.gemspec +14 -15
- data/spec/agent_config_spec.rb +9 -0
- data/spec/agent_spec.rb +154 -18
- data/spec/broker_client_spec.rb +171 -170
- data/spec/dispatcher_spec.rb +24 -8
- data/spec/ha_broker_client_spec.rb +55 -33
- data/spec/monkey_patches/amqp_patch_spec.rb +12 -0
- data/spec/packets_spec.rb +2 -0
- data/spec/sender_spec.rb +140 -69
- data/spec/stats_helper_spec.rb +5 -0
- metadata +54 -53
data/lib/right_agent.rb
CHANGED
@@ -20,31 +20,22 @@
|
|
20
20
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
|
23
|
-
|
23
|
+
# reuse minimal loader to ensure right_agent can safely be required after minimal.
|
24
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'right_agent', 'minimal'))
|
25
|
+
|
24
26
|
require 'amqp'
|
25
|
-
require 'mq'
|
26
27
|
require 'json'
|
27
28
|
require 'yaml'
|
28
29
|
require 'openssl'
|
29
30
|
|
30
|
-
# Cannot use File.normalize_path here because not defined until after this include
|
31
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'right_agent', 'platform'))
|
32
|
-
|
33
|
-
unless defined?(RIGHT_AGENT_BASE_DIR)
|
34
|
-
RIGHT_AGENT_BASE_DIR = File.normalize_path(File.join(File.dirname(__FILE__), 'right_agent'))
|
35
|
-
end
|
36
|
-
|
37
31
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'monkey_patches'))
|
38
|
-
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'agent_config'))
|
39
32
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'payload_formatter'))
|
40
33
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'packets'))
|
41
34
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'enrollment_result'))
|
42
35
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'console'))
|
43
36
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'daemonize'))
|
44
|
-
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'pid_file'))
|
45
37
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'exceptions'))
|
46
38
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'multiplexer'))
|
47
|
-
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'log'))
|
48
39
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'tracer'))
|
49
40
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'audit_formatter'))
|
50
41
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'serialize'))
|
@@ -54,7 +45,6 @@ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'subprocess'))
|
|
54
45
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'stats_helper'))
|
55
46
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'broker_client'))
|
56
47
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'ha_broker_client'))
|
57
|
-
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'command'))
|
58
48
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'agent_identity'))
|
59
49
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'agent_tags_manager'))
|
60
50
|
require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'actor'))
|
@@ -30,7 +30,8 @@ class AgentManager
|
|
30
30
|
|
31
31
|
on_exception { |meth, deliverable, e| RightScale::ExceptionMailer.deliver_notification(meth, deliverable, e) }
|
32
32
|
|
33
|
-
expose :ping, :stats, :set_log_level, :execute, :connect, :disconnect, :
|
33
|
+
expose :ping, :stats, :profile, :set_log_level, :execute, :connect, :disconnect, :connect_failed,
|
34
|
+
:tune_heartbeat, :terminate
|
34
35
|
|
35
36
|
# Valid log levels
|
36
37
|
LEVELS = [:debug, :info, :warn, :error, :fatal]
|
@@ -68,6 +69,48 @@ class AgentManager
|
|
68
69
|
@agent.stats(RightScale::SerializationHelper.symbolize_keys(options))
|
69
70
|
end
|
70
71
|
|
72
|
+
# Profile memory use
|
73
|
+
#
|
74
|
+
# === Parameters
|
75
|
+
# options(Hash):: Request options
|
76
|
+
# :start(Boolean):: Whether to start profiling
|
77
|
+
# :stats(Boolean):: Whether to display profile statistics to stdout
|
78
|
+
# :reset(Boolean):: Whether to reset profile statistics when after displaying them
|
79
|
+
# :stop(Boolean):: Whether to stop profiling
|
80
|
+
#
|
81
|
+
# === Return
|
82
|
+
# (OperationResult):: Empty success result or error result with message
|
83
|
+
def profile(options)
|
84
|
+
require 'memprof'
|
85
|
+
|
86
|
+
options = RightScale::SerializationHelper.symbolize_keys(options)
|
87
|
+
if options[:start]
|
88
|
+
RightScale::Log.info("[profile] Start")
|
89
|
+
$stderr.puts "[profile] Start at #{Time.now}"
|
90
|
+
Memprof.start
|
91
|
+
@profiling = true
|
92
|
+
end
|
93
|
+
|
94
|
+
if options[:stats]
|
95
|
+
return error_result("Profiling has not yet been started") unless @profiling
|
96
|
+
RightScale::Log.info("[profile] GC start")
|
97
|
+
$stderr.puts "[profile] GC at #{Time.now}"
|
98
|
+
GC.start
|
99
|
+
RightScale::Log.info("[profile] Display stats to stderr")
|
100
|
+
$stderr.puts "[profile] Stats at #{Time.now}#{options[:reset] ? ' with reset' : ''}"
|
101
|
+
options[:reset] ? Memprof.stats! : Memprof.stats
|
102
|
+
end
|
103
|
+
|
104
|
+
if options[:stop]
|
105
|
+
return error_result("Profiling has not yet been started") unless @profiling
|
106
|
+
RightScale::Log.info("[profile] Stop")
|
107
|
+
$stderr.puts "[profile] Stop at #{Time.now}"
|
108
|
+
Memprof.stop
|
109
|
+
@profiling = false
|
110
|
+
end
|
111
|
+
success_result
|
112
|
+
end
|
113
|
+
|
71
114
|
# Change log level of agent
|
72
115
|
#
|
73
116
|
# === Parameter
|
@@ -123,7 +166,7 @@ class AgentManager
|
|
123
166
|
res = error_result(error)
|
124
167
|
end
|
125
168
|
rescue Exception => e
|
126
|
-
res = error_result("Failed to connect to broker
|
169
|
+
res = error_result("Failed to connect to broker", e)
|
127
170
|
end
|
128
171
|
res
|
129
172
|
end
|
@@ -146,7 +189,7 @@ class AgentManager
|
|
146
189
|
res = error_result(error)
|
147
190
|
end
|
148
191
|
rescue Exception => e
|
149
|
-
res = error_result("Failed to disconnect from broker
|
192
|
+
res = error_result("Failed to disconnect from broker", e)
|
150
193
|
end
|
151
194
|
res
|
152
195
|
end
|
@@ -167,7 +210,38 @@ class AgentManager
|
|
167
210
|
res = error_result(error)
|
168
211
|
end
|
169
212
|
rescue Exception => e
|
170
|
-
res = error_result("Failed to notify agent that brokers #{options[:brokers]} are unusable
|
213
|
+
res = error_result("Failed to notify agent that brokers #{options[:brokers]} are unusable", e)
|
214
|
+
end
|
215
|
+
res
|
216
|
+
end
|
217
|
+
|
218
|
+
# Tune connection heartbeat frequency for all brokers
|
219
|
+
# Any response to this request is not likely to get through if :immediate is specified
|
220
|
+
# because the broker connections will be in flux
|
221
|
+
# Use of :immediate should be avoided when this is a fanned out request to avoid
|
222
|
+
# overloading the brokers
|
223
|
+
#
|
224
|
+
# === Parameters
|
225
|
+
# options(Hash):: Tune options:
|
226
|
+
# :heartbeat(Integer):: New AMQP connection heartbeat setting, nil or 0 means disable
|
227
|
+
# :immediate(Boolean):: Whether to tune heartbeat immediately rather than defer until next
|
228
|
+
# status check
|
229
|
+
#
|
230
|
+
# === Return
|
231
|
+
# res(RightScale::OperationResult):: Success unless exception is raised
|
232
|
+
def tune_heartbeat(options)
|
233
|
+
options = RightScale::SerializationHelper.symbolize_keys(options)
|
234
|
+
res = success_result
|
235
|
+
begin
|
236
|
+
if options[:immediate]
|
237
|
+
if error = @agent.tune_heartbeat(options[:heartbeat])
|
238
|
+
res = error_result(error)
|
239
|
+
end
|
240
|
+
else
|
241
|
+
@agent.defer_task { @agent.tune_heartbeat(options[:heartbeat]) }
|
242
|
+
end
|
243
|
+
rescue Exception => e
|
244
|
+
res = error_result("Failed to tune heartbeat", e)
|
171
245
|
end
|
172
246
|
res
|
173
247
|
end
|
data/lib/right_agent/agent.rb
CHANGED
@@ -73,6 +73,7 @@ module RightScale
|
|
73
73
|
:check_interval => 5 * 60,
|
74
74
|
:grace_timeout => 30,
|
75
75
|
:prefetch => 1,
|
76
|
+
:heartbeat => 60
|
76
77
|
}
|
77
78
|
|
78
79
|
# Initializes a new agent and establishes an AMQP connection.
|
@@ -97,12 +98,14 @@ module RightScale
|
|
97
98
|
# :retry_timeout(Numeric):: Maximum number of seconds to retry request before give up
|
98
99
|
# :time_to_live(Integer):: Number of seconds before a request expires and is to be ignored
|
99
100
|
# by the receiver, 0 means never expire, defaults to 0
|
100
|
-
# :connect_timeout:: Number of seconds to wait for a broker connection to be established
|
101
|
+
# :connect_timeout(Integer):: Number of seconds to wait for a broker connection to be established
|
101
102
|
# :reconnect_interval(Integer):: Number of seconds between broker reconnect attempts
|
102
103
|
# :ping_interval(Integer):: Minimum number of seconds since last message receipt to ping the mapper
|
103
104
|
# to check connectivity, defaults to 0 meaning do not ping
|
104
|
-
# :check_interval:: Number of seconds between publishing stats and checking for broker connections
|
105
|
+
# :check_interval(Integer):: Number of seconds between publishing stats and checking for broker connections
|
105
106
|
# that failed during agent launch and then attempting to reconnect via the mapper
|
107
|
+
# :heartbeat(Integer):: Number of seconds between AMQP connection heartbeats used to keep
|
108
|
+
# connection alive (e.g., when AMQP broker is behind a firewall), nil or 0 means disable
|
106
109
|
# :grace_timeout(Integer):: Maximum number of seconds to wait after last request received before
|
107
110
|
# terminating regardless of whether there are still unfinished requests
|
108
111
|
# :dup_check(Boolean):: Whether to check for and reject duplicate requests, e.g., due to retries
|
@@ -153,6 +156,7 @@ module RightScale
|
|
153
156
|
@tags << opts[:tag] if opts[:tag]
|
154
157
|
@tags.flatten!
|
155
158
|
@options.freeze
|
159
|
+
@deferred_tasks = []
|
156
160
|
@terminating = false
|
157
161
|
@last_stat_reset_time = @service_start_time = Time.now
|
158
162
|
reset_agent_stats
|
@@ -239,6 +243,57 @@ module RightScale
|
|
239
243
|
@registry.register(actor, prefix)
|
240
244
|
end
|
241
245
|
|
246
|
+
# Tune connection heartbeat frequency for all brokers
|
247
|
+
# Causes a reconnect to each broker
|
248
|
+
#
|
249
|
+
# === Parameters
|
250
|
+
# heartbeat(Integer):: Number of seconds between AMQP connection heartbeats used to keep
|
251
|
+
# connection alive (e.g., when AMQP broker is behind a firewall), nil or 0 means disable
|
252
|
+
#
|
253
|
+
# === Return
|
254
|
+
# res(String|nil):: Error message if failed, otherwise nil
|
255
|
+
def tune_heartbeat(heartbeat)
|
256
|
+
res = nil
|
257
|
+
begin
|
258
|
+
@broker.heartbeat = heartbeat
|
259
|
+
update_configuration(:heartbeat => heartbeat)
|
260
|
+
ids = []
|
261
|
+
all = @broker.all
|
262
|
+
all.each do |id|
|
263
|
+
begin
|
264
|
+
host, port, index, priority, island_id = @broker.identity_parts(id)
|
265
|
+
@broker.connect(host, port, index, priority, island = nil, force = true) do |id|
|
266
|
+
@broker.connection_status(:one_off => @options[:connect_timeout], :brokers => [id]) do |status|
|
267
|
+
begin
|
268
|
+
if status == :connected
|
269
|
+
setup_queues([id])
|
270
|
+
tuned = (heartbeat && heartbeat != 0) ? "Tuned heartbeat to #{heartbeat} seconds" : "Disabled heartbeat"
|
271
|
+
Log.info("[setup] #{tuned} for broker #{id}")
|
272
|
+
else
|
273
|
+
Log.error("Failed to reconnect to broker #{id} to tune heartbeat, status #{status.inspect}")
|
274
|
+
end
|
275
|
+
rescue Exception => e
|
276
|
+
Log.error("Failed to setup queues for broker #{id} when tuning heartbeat", e, :trace)
|
277
|
+
@exceptions.track("tune heartbeat", e)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
ids << id
|
282
|
+
rescue Exception => e
|
283
|
+
res = Log.format("Failed to reconnect to broker #{id} to tune heartbeat", e)
|
284
|
+
Log.error("Failed to reconnect to broker #{id} to tune heartbeat", e, :trace)
|
285
|
+
@exceptions.track("tune heartbeat", e)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
res = "Failed to tune heartbeat for brokers #{(all - ids).inspect}" unless (all - ids).empty?
|
289
|
+
rescue Exception => e
|
290
|
+
res = Log.format("Failed tuning broker connection heartbeat", e)
|
291
|
+
Log.error("Failed tuning broker connection heartbeat", e, :trace)
|
292
|
+
@exceptions.track("tune heartbeat", e)
|
293
|
+
end
|
294
|
+
res
|
295
|
+
end
|
296
|
+
|
242
297
|
# Connect to an additional broker or reconnect it if connection has failed
|
243
298
|
# Subscribe to identity queue on this broker
|
244
299
|
# Update config file if this is a new broker
|
@@ -384,6 +439,17 @@ module RightScale
|
|
384
439
|
true
|
385
440
|
end
|
386
441
|
|
442
|
+
# Defer task until next status check
|
443
|
+
#
|
444
|
+
# === Block
|
445
|
+
# Required block to be activated on next status check
|
446
|
+
#
|
447
|
+
# === Return
|
448
|
+
# true:: Always return true
|
449
|
+
def defer_task(&task)
|
450
|
+
@deferred_tasks << task
|
451
|
+
end
|
452
|
+
|
387
453
|
# Gracefully terminate execution by allowing unfinished tasks to complete
|
388
454
|
# Immediately terminate if called a second time
|
389
455
|
#
|
@@ -462,6 +528,7 @@ module RightScale
|
|
462
528
|
result = OperationResult.success("name" => @agent_name,
|
463
529
|
"identity" => @identity,
|
464
530
|
"hostname" => Socket.gethostname,
|
531
|
+
"memory" => Platform.process.resident_set_size,
|
465
532
|
"version" => AgentConfig.protocol_version,
|
466
533
|
"brokers" => @broker.stats(reset),
|
467
534
|
"agent stats" => agent_stats(reset),
|
@@ -674,12 +741,22 @@ module RightScale
|
|
674
741
|
true
|
675
742
|
end
|
676
743
|
|
677
|
-
# Check status of agent by gathering current operation statistics and publishing them
|
678
|
-
#
|
744
|
+
# Check status of agent by gathering current operation statistics and publishing them,
|
745
|
+
# executing any deferred tasks, and finishing any queue setup
|
679
746
|
#
|
680
747
|
# === Return
|
681
748
|
# true:: Always return true
|
682
749
|
def check_status
|
750
|
+
@deferred_tasks.reject! do |t|
|
751
|
+
begin
|
752
|
+
t.call
|
753
|
+
rescue Exception => e
|
754
|
+
Log.error("Failed to perform deferred task", e)
|
755
|
+
@exceptions.track("check status", e)
|
756
|
+
end
|
757
|
+
true
|
758
|
+
end
|
759
|
+
|
683
760
|
begin
|
684
761
|
finish_setup
|
685
762
|
rescue Exception => e
|
@@ -63,7 +63,7 @@ module RightScale
|
|
63
63
|
module AgentConfig
|
64
64
|
|
65
65
|
# Current agent protocol version
|
66
|
-
PROTOCOL_VERSION =
|
66
|
+
PROTOCOL_VERSION = 18
|
67
67
|
|
68
68
|
# Current agent protocol version
|
69
69
|
#
|
@@ -344,6 +344,22 @@ module RightScale
|
|
344
344
|
options || {}
|
345
345
|
end
|
346
346
|
|
347
|
+
# Agents that are currently running
|
348
|
+
#
|
349
|
+
# === Parameters
|
350
|
+
# (Regexp):: Pattern that agent name must match to be included
|
351
|
+
#
|
352
|
+
# === Return
|
353
|
+
# (Array):: Name of running agents
|
354
|
+
def self.running_agents(pattern = //)
|
355
|
+
AgentConfig.cfg_agents.select do |agent_name|
|
356
|
+
agent_name =~ pattern &&
|
357
|
+
(pid_file = AgentConfig.pid_file(agent_name)) &&
|
358
|
+
(pid = pid_file.read_pid[:pid]) &&
|
359
|
+
(Process.getpgid(pid) rescue -1) != -1
|
360
|
+
end.sort
|
361
|
+
end
|
362
|
+
|
347
363
|
protected
|
348
364
|
|
349
365
|
# Convert value to array if not an array, unless nil
|
@@ -40,7 +40,7 @@ module RightScale
|
|
40
40
|
# === Return
|
41
41
|
# true:: Always return true
|
42
42
|
def tags
|
43
|
-
do_query do |result|
|
43
|
+
do_query(nil, @agent.identity) do |result|
|
44
44
|
if result.kind_of?(Hash)
|
45
45
|
yield(result.size == 1 ? result.values.first['tags'] : [])
|
46
46
|
else
|
@@ -178,7 +178,7 @@ module RightScale
|
|
178
178
|
# true:: Always return true
|
179
179
|
def do_query(tags = nil, agent_ids = nil, raw = false)
|
180
180
|
agent_check
|
181
|
-
payload = {:
|
181
|
+
payload = {:agent_identity => @agent.identity}
|
182
182
|
payload[:tags] = ensure_flat_array_value(tags) unless tags.nil? || tags.empty?
|
183
183
|
payload[:agent_ids] = ensure_flat_array_value(agent_ids) unless agent_ids.nil? || agent_ids.empty?
|
184
184
|
request = RightScale::IdempotentRequest.new("/mapper/query_tags", payload)
|
@@ -37,8 +37,8 @@ module RightScale
|
|
37
37
|
:failed # Failed to connect due to internal failure or AMQP failure to connect
|
38
38
|
]
|
39
39
|
|
40
|
-
# (
|
41
|
-
attr_reader :
|
40
|
+
# (AMQP::Channel) Channel of AMQP connection used by this client
|
41
|
+
attr_reader :channel
|
42
42
|
|
43
43
|
# (String) Broker identity
|
44
44
|
attr_reader :identity
|
@@ -99,6 +99,8 @@ module RightScale
|
|
99
99
|
# :vhost(String):: Virtual host path name
|
100
100
|
# :insist(Boolean):: Whether to suppress redirection of connection
|
101
101
|
# :reconnect_interval(Integer):: Number of seconds between reconnect attempts
|
102
|
+
# :heartbeat(Integer):: Number of seconds between AMQP connection heartbeats used to keep
|
103
|
+
# connection alive, e.g., when AMQP broker is behind a firewall
|
102
104
|
# :prefetch(Integer):: Maximum number of messages the AMQP broker is to prefetch for the agent
|
103
105
|
# before it receives an ack. Value 1 ensures that only last unacknowledged gets redelivered
|
104
106
|
# if the agent crashes. Value 0 means unlimited prefetch.
|
@@ -217,13 +219,13 @@ module RightScale
|
|
217
219
|
|
218
220
|
begin
|
219
221
|
Log.info("[setup] Subscribing queue #{queue[:name]}#{to_exchange} on broker #{@alias}")
|
220
|
-
q = @
|
222
|
+
q = @channel.queue(queue[:name], queue_options)
|
221
223
|
@queues << q
|
222
224
|
if exchange
|
223
|
-
x = @
|
225
|
+
x = @channel.__send__(exchange[:type], exchange[:name], exchange_options)
|
224
226
|
binding = q.bind(x, options[:key] ? {:key => options[:key]} : {})
|
225
227
|
if exchange2 = options[:exchange2]
|
226
|
-
q.bind(@
|
228
|
+
q.bind(@channel.__send__(exchange2[:type], exchange2[:name], exchange2[:options] || {}))
|
227
229
|
end
|
228
230
|
q = binding
|
229
231
|
end
|
@@ -319,8 +321,8 @@ module RightScale
|
|
319
321
|
return false unless usable?
|
320
322
|
begin
|
321
323
|
Log.info("[setup] Declaring #{name} #{type.to_s} on broker #{@alias}")
|
322
|
-
|
323
|
-
@
|
324
|
+
delete_amqp_resources(:queue, name)
|
325
|
+
@channel.__send__(type, name, options)
|
324
326
|
true
|
325
327
|
rescue Exception => e
|
326
328
|
Log.error("Failed declaring #{type.to_s} #{name} on broker #{@alias}", e, :trace)
|
@@ -361,8 +363,8 @@ module RightScale
|
|
361
363
|
end
|
362
364
|
Log.debug("... publish options #{options.inspect}, exchange #{exchange[:name]}, " +
|
363
365
|
"type #{exchange[:type]}, options #{exchange[:options].inspect}")
|
364
|
-
|
365
|
-
@
|
366
|
+
delete_amqp_resources(exchange[:type], exchange[:name]) if exchange_options[:declare]
|
367
|
+
@channel.__send__(exchange[:type], exchange[:name], exchange_options).publish(message, options)
|
366
368
|
true
|
367
369
|
rescue Exception => e
|
368
370
|
Log.error("Failed publishing to exchange #{exchange.inspect} on broker #{@alias}", e, :trace)
|
@@ -390,7 +392,7 @@ module RightScale
|
|
390
392
|
# === Return
|
391
393
|
# true:: Always return true
|
392
394
|
def return_message
|
393
|
-
@
|
395
|
+
@channel.return_message do |info, message|
|
394
396
|
begin
|
395
397
|
to = if info.exchange && !info.exchange.empty? then info.exchange else info.routing_key end
|
396
398
|
reason = info.reply_text
|
@@ -418,14 +420,14 @@ module RightScale
|
|
418
420
|
begin
|
419
421
|
@queues.reject! do |q|
|
420
422
|
if q.name == name
|
421
|
-
@
|
423
|
+
@channel.queue(name, options.merge(:no_declare => true)).delete
|
422
424
|
deleted = true
|
423
425
|
end
|
424
426
|
end
|
425
427
|
unless deleted
|
426
428
|
# Allowing declare to happen since queue may not exist and do not want NOT_FOUND
|
427
429
|
# failure to cause AMQP channel to close
|
428
|
-
@
|
430
|
+
@channel.queue(name, options).delete
|
429
431
|
deleted = true
|
430
432
|
end
|
431
433
|
rescue Exception => e
|
@@ -436,6 +438,19 @@ module RightScale
|
|
436
438
|
deleted
|
437
439
|
end
|
438
440
|
|
441
|
+
# Delete resources from local AMQP cache
|
442
|
+
#
|
443
|
+
# === Parameters
|
444
|
+
# type(Symbol):: Type of AMQP object
|
445
|
+
# name(String):: Name of object
|
446
|
+
#
|
447
|
+
# === Return
|
448
|
+
# true:: Always return true
|
449
|
+
def delete_amqp_resources(type, name)
|
450
|
+
@channel.__send__(type == :queue ? :queues : :exchanges).delete(name)
|
451
|
+
true
|
452
|
+
end
|
453
|
+
|
439
454
|
# Close broker connection
|
440
455
|
#
|
441
456
|
# === Parameters
|
@@ -520,7 +535,7 @@ module RightScale
|
|
520
535
|
# Makes client callback with :connected or :disconnected status if boundary crossed
|
521
536
|
#
|
522
537
|
# === Parameters
|
523
|
-
# status(Symbol):: Status of connection (:connected, :
|
538
|
+
# status(Symbol):: Status of connection (:connected, :disconnected, :stopping, :failed, :closed)
|
524
539
|
#
|
525
540
|
# === Return
|
526
541
|
# true:: Always return true
|
@@ -528,11 +543,6 @@ module RightScale
|
|
528
543
|
# Do not let closed connection regress to failed
|
529
544
|
return true if status == :failed && @status == :closed
|
530
545
|
|
531
|
-
# Wait until connection is ready (i.e. handshake with broker is completed) before
|
532
|
-
# changing our status to connected
|
533
|
-
return true if status == :connected
|
534
|
-
status = :connected if status == :ready
|
535
|
-
|
536
546
|
before = @status
|
537
547
|
@status = status
|
538
548
|
|
@@ -574,11 +584,12 @@ module RightScale
|
|
574
584
|
:host => address[:host],
|
575
585
|
:port => address[:port],
|
576
586
|
:insist => @options[:insist] || false,
|
587
|
+
:heartbeat => @options[:heartbeat],
|
577
588
|
:reconnect_delay => lambda { rand(reconnect_interval) },
|
578
589
|
:reconnect_interval => reconnect_interval)
|
579
|
-
@
|
580
|
-
@
|
581
|
-
@
|
590
|
+
@channel = AMQP::Channel.new(@connection)
|
591
|
+
@channel.__send__(:connection).connection_status { |status| update_status(status) }
|
592
|
+
@channel.prefetch(@options[:prefetch]) if @options[:prefetch]
|
582
593
|
rescue Exception => e
|
583
594
|
@status = :failed
|
584
595
|
@failures.update
|
@@ -653,19 +664,6 @@ module RightScale
|
|
653
664
|
true
|
654
665
|
end
|
655
666
|
|
656
|
-
# Delete object from local AMQP cache in case it is no longer consistent with broker
|
657
|
-
#
|
658
|
-
# === Parameters
|
659
|
-
# type(Symbol):: Type of AMQP object
|
660
|
-
# name(String):: Name of object
|
661
|
-
#
|
662
|
-
# === Return
|
663
|
-
# true:: Always return true
|
664
|
-
def delete_from_cache(type, name)
|
665
|
-
@mq.__send__(type == :queue ? :queues : :exchanges).delete(name)
|
666
|
-
true
|
667
|
-
end
|
668
|
-
|
669
667
|
# Execute packet receive callback, make it a separate method to ease instrumentation
|
670
668
|
#
|
671
669
|
# === Parameters
|