smith 0.5.8 → 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/bin/agency +49 -21
- data/bin/smithctl +51 -48
- data/lib/smith.rb +21 -17
- data/lib/smith/acl_compiler.rb +6 -3
- data/lib/smith/agent.rb +13 -24
- data/lib/smith/agent_monitoring.rb +5 -5
- data/lib/smith/agent_process.rb +4 -4
- data/lib/smith/application/agency.rb +11 -7
- data/lib/smith/bootstrap.rb +4 -4
- data/lib/smith/command.rb +26 -5
- data/lib/smith/command_base.rb +2 -2
- data/lib/smith/commands/agency/list.rb +11 -26
- data/lib/smith/commands/agency/logger.rb +1 -1
- data/lib/smith/commands/agency/restart.rb +1 -1
- data/lib/smith/commands/agency/start.rb +20 -7
- data/lib/smith/commands/agency/stop.rb +23 -10
- data/lib/smith/commands/agency/version.rb +31 -0
- data/lib/smith/commands/smithctl/commands.rb +1 -13
- data/lib/smith/commands/smithctl/pop.rb +34 -28
- data/lib/smith/commands/smithctl/{cat.rb → push.rb} +3 -3
- data/lib/smith/commands/smithctl/rm.rb +20 -0
- data/lib/smith/commands/smithctl/top.rb +1 -1
- data/lib/smith/config.rb +15 -0
- data/lib/smith/daemon.rb +68 -0
- data/lib/smith/{messaging/exceptions.rb → exceptions.rb} +6 -0
- data/lib/smith/logger.rb +2 -3
- data/lib/smith/messaging/acl/agent_keepalive.proto +2 -2
- data/lib/smith/messaging/acl/agent_lifecycle.proto +2 -2
- data/lib/smith/messaging/acl/default.rb +1 -1
- data/lib/smith/messaging/endpoint.rb +5 -5
- data/lib/smith/messaging/receiver.rb +19 -19
- data/lib/smith/messaging/sender.rb +3 -3
- data/lib/smith/version.rb +3 -0
- metadata +52 -41
- data/lib/smith/commands/agency/agency_version.rb +0 -24
- data/lib/smith/commands/agency/state.rb +0 -20
- data/lib/smith/commands/smithctl/smithctl_version.rb +0 -22
@@ -3,14 +3,10 @@ module Smith
|
|
3
3
|
module Commands
|
4
4
|
class Commands < CommandBase
|
5
5
|
def execute
|
6
|
-
commands = (target.empty?) ?
|
6
|
+
commands = (target.empty?) ? Command.commands : target
|
7
7
|
responder.value(format(commands))
|
8
8
|
end
|
9
9
|
|
10
|
-
def list_commands(type)
|
11
|
-
list_command_files(type).map {|command| to_command_name(command) }
|
12
|
-
end
|
13
|
-
|
14
10
|
def format(commands)
|
15
11
|
if options[:long]
|
16
12
|
c = instantiate_commands(commands)
|
@@ -30,14 +26,6 @@ module Smith
|
|
30
26
|
|
31
27
|
private
|
32
28
|
|
33
|
-
def list_command_files(type)
|
34
|
-
Pathname.glob(Command.base_path.join(type).join("**/*.rb"))
|
35
|
-
end
|
36
|
-
|
37
|
-
def to_command_name(path)
|
38
|
-
path.basename(".rb").to_s
|
39
|
-
end
|
40
|
-
|
41
29
|
def instantiate_commands(commands)
|
42
30
|
commands.sort.inject({}) do |a, command|
|
43
31
|
a.tap do |acc|
|
@@ -9,36 +9,44 @@ module Smith
|
|
9
9
|
when 0
|
10
10
|
responder.value("No queue specified. Please specify a queue.")
|
11
11
|
when 1
|
12
|
-
|
12
|
+
|
13
|
+
queue = target.first
|
14
|
+
|
15
|
+
# What to do if there is a channel error.
|
16
|
+
Smith.on_error do |ch,channel_close|
|
17
|
+
case channel_close.reply_code
|
18
|
+
when 404
|
19
|
+
responder.value("Queue does not exist: #{queue}")
|
20
|
+
else
|
21
|
+
responder.value("Unknown error: #{channel_close.reply_text}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Messaging::Receiver.new(queue, :auto_ack => false, :passive => true).ready do |receiver|
|
13
26
|
callback = proc do
|
14
|
-
work = proc do |n,iter|
|
27
|
+
work = proc do |acc,n,iter|
|
15
28
|
receiver.pop do |r|
|
16
|
-
|
29
|
+
if options[:remove]
|
30
|
+
r.ack
|
31
|
+
else
|
32
|
+
r.reject(:requeue => true)
|
33
|
+
end
|
34
|
+
|
35
|
+
acc[:result] << print_message(r.payload) if options[:print]
|
36
|
+
acc[:count] += 1
|
37
|
+
|
38
|
+
iter.return(acc)
|
17
39
|
end
|
18
40
|
end
|
19
41
|
|
20
|
-
finished = proc do |
|
42
|
+
finished = proc do |acc|
|
21
43
|
responder.value do
|
22
|
-
|
23
|
-
|
24
|
-
result.inject([]) do |a,r|
|
25
|
-
a.tap do |acc|
|
26
|
-
r.ack
|
27
|
-
acc << print_message(r.payload)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
else
|
31
|
-
result.inject([]) do |a,r|
|
32
|
-
a.tap do |acc|
|
33
|
-
r.reject(:requeue => true)
|
34
|
-
acc << print_message(r.payload)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end.join("\n")
|
44
|
+
logger.debug { "Removing #{acc[:count]} message from #{receiver.queue_name}" }
|
45
|
+
acc[:result].join("\n")
|
38
46
|
end
|
39
47
|
end
|
40
48
|
|
41
|
-
EM::Iterator.new(0..options[:number] - 1).
|
49
|
+
EM::Iterator.new(0..options[:number] - 1).inject({:count => 0, :result => []}, work, finished)
|
42
50
|
end
|
43
51
|
|
44
52
|
errback = proc {responder.value(nil)}
|
@@ -46,19 +54,17 @@ module Smith
|
|
46
54
|
receiver.messages?(callback, errback)
|
47
55
|
end
|
48
56
|
else
|
49
|
-
responder.value("You can only
|
57
|
+
responder.value("You can only specify one queue at a time")
|
50
58
|
end
|
51
59
|
end
|
52
60
|
|
53
61
|
private
|
54
62
|
|
55
63
|
def print_message(message)
|
56
|
-
if options[:
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
message.inspect
|
61
|
-
end
|
64
|
+
if options[:json]
|
65
|
+
message.as_json
|
66
|
+
else
|
67
|
+
message.inspect
|
62
68
|
end
|
63
69
|
end
|
64
70
|
|
@@ -4,7 +4,7 @@ require 'multi_json'
|
|
4
4
|
|
5
5
|
module Smith
|
6
6
|
module Commands
|
7
|
-
class
|
7
|
+
class Push < CommandBase
|
8
8
|
def execute
|
9
9
|
if target.size == 0
|
10
10
|
responder.value("No queue specified. Please specify a queue.")
|
@@ -23,7 +23,7 @@ module Smith
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
Messaging::Sender.new(target.first, :auto_delete => options[:dynamic], :persistent => true, :nowait => false, :strict => true).ready do |sender|
|
27
27
|
|
28
28
|
work = proc do |n,iter|
|
29
29
|
sender.publish(json_to_payload(data, options[:type])) do
|
@@ -48,7 +48,7 @@ module Smith
|
|
48
48
|
private
|
49
49
|
|
50
50
|
def json_to_payload(data, type)
|
51
|
-
|
51
|
+
ACL::Payload.new(type.to_sym).content do |m|
|
52
52
|
MultiJson.load(data, :symbolize_keys => true).each do |k,v|
|
53
53
|
m.send("#{k}=".to_sym, v)
|
54
54
|
end
|
@@ -7,6 +7,17 @@ module Smith
|
|
7
7
|
when 0
|
8
8
|
responder.value("No queue specified. Please specify a queue.")
|
9
9
|
else
|
10
|
+
Smith.on_error do |ch,channel_close|
|
11
|
+
case channel_close.reply_code
|
12
|
+
when 404
|
13
|
+
responder.value("No such queue: #{extract_queue(channel_close.reply_text)}")
|
14
|
+
when 406
|
15
|
+
responder.value("Queue not empty: #{extract_queue(channel_close.reply_text)}. Use -f to force remove")
|
16
|
+
else
|
17
|
+
responder.value("Unknown error: #{channel_close.reply_text}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
10
21
|
target.each do |queue_name|
|
11
22
|
Smith.channel.queue("smith.#{queue_name}", :passive => true) do |queue|
|
12
23
|
queue_options = (options[:force]) ? {} : {:if_unused => true, :if_empty => true}
|
@@ -26,6 +37,15 @@ module Smith
|
|
26
37
|
opt :force, "force the removal even if there are messages on the queue", :short => :f
|
27
38
|
opt :verbose, "print the number of messages deleted", :short => :v
|
28
39
|
end
|
40
|
+
|
41
|
+
def extract_queue(message)
|
42
|
+
match = /.*?'(.*?)'.*$/.match(message) #[1]
|
43
|
+
if match && match[1]
|
44
|
+
match[1].sub(/smith\./, '')
|
45
|
+
else
|
46
|
+
message
|
47
|
+
end
|
48
|
+
end
|
29
49
|
end
|
30
50
|
end
|
31
51
|
end
|
@@ -9,7 +9,7 @@ module Smith
|
|
9
9
|
Curses.init_screen()
|
10
10
|
win = Curses::Window.new(Curses.lines, Curses.cols, 0, 0)
|
11
11
|
|
12
|
-
|
12
|
+
Messaging::Receiver.new('agent.stats', :durable => false, :auto_delete => false).ready do |receiver|
|
13
13
|
receiver.subscribe do |r|
|
14
14
|
payload = r.payload
|
15
15
|
win.setpos(0,0)
|
data/lib/smith/config.rb
CHANGED
@@ -3,6 +3,16 @@ module Smith
|
|
3
3
|
class Config
|
4
4
|
|
5
5
|
@@config = Optimism.new.tap do |o|
|
6
|
+
o.agency do |a|
|
7
|
+
a.timeout = 30
|
8
|
+
end
|
9
|
+
|
10
|
+
o.agent do |a|
|
11
|
+
a.monitor = false
|
12
|
+
a.singleton = true
|
13
|
+
a.metadata = ''
|
14
|
+
end
|
15
|
+
|
6
16
|
o.amqp do |a|
|
7
17
|
a.publish do |p|
|
8
18
|
p.ack = true
|
@@ -12,6 +22,11 @@ module Smith
|
|
12
22
|
a.pop.ack = true
|
13
23
|
a.subscribe.ack = true
|
14
24
|
end
|
25
|
+
|
26
|
+
o.agency do |a|
|
27
|
+
a.timeout = 30
|
28
|
+
end
|
29
|
+
|
15
30
|
o.logging do |l|
|
16
31
|
l.trace = false
|
17
32
|
l.level = :debug
|
data/lib/smith/daemon.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'daemons/daemonize'
|
4
|
+
require 'daemons/pidfile'
|
5
|
+
|
6
|
+
module Smith
|
7
|
+
class Daemon
|
8
|
+
|
9
|
+
include Logger
|
10
|
+
|
11
|
+
def initialize(name, daemonise, dir=nil)
|
12
|
+
@name = name
|
13
|
+
@daemonise = daemonise
|
14
|
+
@pid = Daemons::PidFile.new(pid_dir(dir), @name)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Daemonise the process if the daemonise option is true, otherwise do nothing.
|
18
|
+
def daemonise
|
19
|
+
unlink_pid_file
|
20
|
+
|
21
|
+
if @daemonise
|
22
|
+
Daemonize::daemonize('/dev/null', @name)
|
23
|
+
else
|
24
|
+
$0 = @name
|
25
|
+
end
|
26
|
+
|
27
|
+
@pid.pid = Process.pid
|
28
|
+
logger.debug { "Pid file: #{@pid.filename}" }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Check to see if the program is running. This checks for the existance
|
32
|
+
# of a pid file and if there is checks to see if the pid exists.
|
33
|
+
def running?
|
34
|
+
pid_files = Daemons::PidFile.find_files(@pid.dir, @name)
|
35
|
+
|
36
|
+
if pid_files.empty?
|
37
|
+
false
|
38
|
+
else
|
39
|
+
pid = File.read(pid_files.first).to_i
|
40
|
+
pid > 0 && Daemons::Pid.running?(pid)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def unlink_pid_file
|
45
|
+
p = Pathname.new(@pid.filename)
|
46
|
+
if p.exist?
|
47
|
+
logger.verbose { "Removing pid file." }
|
48
|
+
p.unlink
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Get the pid directory. This checks for the command line option,
|
55
|
+
# then the config and finally use the tmp directory.
|
56
|
+
def pid_dir(dir)
|
57
|
+
if dir
|
58
|
+
dir
|
59
|
+
else
|
60
|
+
if Smith.config.agency._has_key?(:pid_dir)
|
61
|
+
Smith.config.agency.pid_dir
|
62
|
+
else
|
63
|
+
Dir.tmpdir
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -1,5 +1,11 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
module Smith
|
3
|
+
class UnknownEnvironmentError < RuntimeError
|
4
|
+
def initialize(message=nil)
|
5
|
+
super("Invalid environment: #{message || Smith.environment}")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
module Messaging
|
4
10
|
class IncompletePayload < RuntimeError; end
|
5
11
|
class IncorrectPayloadType < RuntimeError; end
|
data/lib/smith/logger.rb
CHANGED
@@ -22,9 +22,8 @@ module Smith
|
|
22
22
|
@@__date_pattern = Smith::Config.get.logging.default_date_pattern
|
23
23
|
@@__level = Smith::Config.get.logging.level
|
24
24
|
@@__trace = Smith::Config.get.logging.trace
|
25
|
-
@@__appender = Smith::Config.get.logging.appender._data.
|
26
|
-
|
27
|
-
end
|
25
|
+
@@__appender = Smith::Config.get.logging.appender._data.clone
|
26
|
+
@@__appender[:type] = Logging::Appenders.const_get(Extlib::Inflection.camelize(Smith::Config.get.logging.appender.type))
|
28
27
|
|
29
28
|
def log_level(level=nil)
|
30
29
|
if level
|
@@ -4,9 +4,9 @@ package Smith.ACL;
|
|
4
4
|
message AgentLifecycle {
|
5
5
|
required string state = 1;
|
6
6
|
required string name = 2;
|
7
|
-
optional
|
7
|
+
optional int64 pid = 3;
|
8
8
|
optional bool monitor = 4;
|
9
9
|
optional bool singleton = 5;
|
10
10
|
optional string metadata = 6;
|
11
|
-
optional
|
11
|
+
optional int64 started_at = 7;
|
12
12
|
}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
module Smith
|
3
3
|
module ACL
|
4
4
|
|
5
|
-
# Default message. This takes any
|
5
|
+
# Default message. This takes any object that can be marshalled. If
|
6
6
|
# no content is passed in on the constructor then an the message is
|
7
7
|
# assigned an empty Hash. method_missing is declared and will update
|
8
8
|
# the hash.
|
@@ -4,10 +4,10 @@ module Smith
|
|
4
4
|
class Endpoint
|
5
5
|
include Logger
|
6
6
|
|
7
|
-
attr_accessor :
|
7
|
+
attr_accessor :denormalized_queue_name, :queue_name
|
8
8
|
|
9
9
|
def initialize(queue_name, options)
|
10
|
-
@
|
10
|
+
@denormalized_queue_name = queue_name
|
11
11
|
@queue_name = normalise(queue_name)
|
12
12
|
@message_counts = Hash.new(0)
|
13
13
|
@options = options
|
@@ -22,7 +22,7 @@ module Smith
|
|
22
22
|
logger.error { "Properties: #{metadata.properties}" }
|
23
23
|
end
|
24
24
|
|
25
|
-
logger.verbose { "Creating queue: [queue]:#{
|
25
|
+
logger.verbose { "Creating queue: [queue]:#{denormalized_queue_name} [options]:#{options.queue}" }
|
26
26
|
|
27
27
|
Smith.channel.queue(queue_name, options.queue) do |queue|
|
28
28
|
@queue = queue
|
@@ -50,7 +50,7 @@ module Smith
|
|
50
50
|
@message_counts[queue_name]
|
51
51
|
end
|
52
52
|
|
53
|
-
def messages?(blk=nil, err=proc {logger.debug { "No messages on #{@
|
53
|
+
def messages?(blk=nil, err=proc {logger.debug { "No messages on #{@denormalized_queue_name}" } })
|
54
54
|
number_of_messages do |n|
|
55
55
|
if n > 0
|
56
56
|
if blk.respond_to? :call
|
@@ -64,7 +64,7 @@ module Smith
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
def consumers?(blk=nil, err=proc {logger.debug { "Nothing listening on #{@
|
67
|
+
def consumers?(blk=nil, err=proc {logger.debug { "Nothing listening on #{@denormalized_queue_name}" } })
|
68
68
|
number_of_consumers do |n|
|
69
69
|
if n > 0
|
70
70
|
if blk.respond_to? :call
|
@@ -21,7 +21,7 @@ module Smith
|
|
21
21
|
def subscribe(&block)
|
22
22
|
if !@queue.subscribed?
|
23
23
|
opts = options.subscribe
|
24
|
-
logger.verbose { "Subscribing to: [queue]:#{
|
24
|
+
logger.verbose { "Subscribing to: [queue]:#{denormalized_queue_name} [options]:#{opts}" }
|
25
25
|
queue.subscribe(opts) do |metadata,payload|
|
26
26
|
if payload
|
27
27
|
if @payload_type.empty? || @payload_type.include?(metadata.type.to_sym)
|
@@ -33,7 +33,7 @@ module Smith
|
|
33
33
|
raise IncorrectPayloadType, "This queue can only accept the following payload types: #{@payload_type.to_a.to_s}"
|
34
34
|
end
|
35
35
|
else
|
36
|
-
logger.verbose { "Received null message on: #{
|
36
|
+
logger.verbose { "Received null message on: #{denormalized_queue_name} [options]:#{opts}" }
|
37
37
|
end
|
38
38
|
end
|
39
39
|
else
|
@@ -68,8 +68,8 @@ module Smith
|
|
68
68
|
# to auto ack or not. This is because it can get called twice and we don't
|
69
69
|
# want to ack more than once or an error will be thrown.
|
70
70
|
def thread(reply, &block)
|
71
|
-
logger.verbose { "Threads: [queue]: #{
|
72
|
-
logger.verbose { "auto_ack: [queue]: #{
|
71
|
+
logger.verbose { "Threads: [queue]: #{denormalized_queue_name}: #{threading?}" }
|
72
|
+
logger.verbose { "auto_ack: [queue]: #{denormalized_queue_name}: #{auto_ack?}" }
|
73
73
|
if threading?
|
74
74
|
EM.defer do
|
75
75
|
block.call(reply)
|
@@ -81,7 +81,7 @@ module Smith
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
# I'm not terribly happy about this class. It's
|
84
|
+
# I'm not terribly happy about this class. It's publicly visible and it contains
|
85
85
|
# some gross violations of Ruby's protection mechanism. I suspect it's an indication
|
86
86
|
# of a more fundamental design flaw. I will leave it as is for the time being but
|
87
87
|
# this really needs to be reviewed. FIXME review this class.
|
@@ -100,10 +100,10 @@ module Smith
|
|
100
100
|
|
101
101
|
if undecoded_payload
|
102
102
|
@payload = ACL::Payload.decode(undecoded_payload, metadata.type)
|
103
|
-
logger.verbose { "Received content on: [queue]: #{
|
104
|
-
logger.verbose { "Payload content: [queue]: #{
|
103
|
+
logger.verbose { "Received content on: [queue]: #{denormalized_queue_name}." }
|
104
|
+
logger.verbose { "Payload content: [queue]: #{denormalized_queue_name}, [metadata type]: #{metadata.type}, [message]: #{payload.inspect}" }
|
105
105
|
else
|
106
|
-
logger.verbose { "Received nil content on: [queue]: #{
|
106
|
+
logger.verbose { "Received nil content on: [queue]: #{denormalized_queue_name}." }
|
107
107
|
@payload = nil
|
108
108
|
@nil_message = true
|
109
109
|
end
|
@@ -122,7 +122,7 @@ module Smith
|
|
122
122
|
else
|
123
123
|
# Null responder. If a call on the responder is made log a warning. Something is wrong.
|
124
124
|
responder.callback do |return_value|
|
125
|
-
logger.error { "You are responding to a message that has no reply_to on queue: #{
|
125
|
+
logger.error { "You are responding to a message that has no reply_to on queue: #{denormalized_queue_name}." }
|
126
126
|
logger.verbose { "Queue options: #{@metadata.exchange}." }
|
127
127
|
end
|
128
128
|
end
|
@@ -159,8 +159,8 @@ module Smith
|
|
159
159
|
o[:type] = metadata.type
|
160
160
|
end
|
161
161
|
|
162
|
-
logger.verbose { "Requeuing to: #{
|
163
|
-
logger.verbose { "Requeuing to: #{
|
162
|
+
logger.verbose { "Requeuing to: #{denormalized_queue_name}. [options]: #{opts}" }
|
163
|
+
logger.verbose { "Requeuing to: #{denormalized_queue_name}. [message]: #{ACL::Payload.decode(@undecoded_payload, metadata.type)}" }
|
164
164
|
|
165
165
|
@receiver.send(:exchange).publish(@undecoded_payload, opts)
|
166
166
|
end
|
@@ -184,7 +184,7 @@ module Smith
|
|
184
184
|
end
|
185
185
|
|
186
186
|
def queue_name
|
187
|
-
|
187
|
+
denormalized_queue_name
|
188
188
|
end
|
189
189
|
|
190
190
|
private
|
@@ -193,16 +193,16 @@ module Smith
|
|
193
193
|
if current_requeue_number < count
|
194
194
|
method = "#{strategy}_strategy".to_sym
|
195
195
|
if respond_to?(method, true)
|
196
|
-
|
197
|
-
@on_requeue.call(
|
198
|
-
EM.add_timer(
|
199
|
-
block.call(
|
196
|
+
cumulative_delay = send(method, delay)
|
197
|
+
@on_requeue.call(cumulative_delay, current_requeue_number + 1)
|
198
|
+
EM.add_timer(cumulative_delay) do
|
199
|
+
block.call(cumulative_delay, current_requeue_number + 1)
|
200
200
|
end
|
201
201
|
else
|
202
202
|
raise RuntimeError, "Unknown requeue strategy. #{method}"
|
203
203
|
end
|
204
204
|
else
|
205
|
-
@on_requeue_error.call(
|
205
|
+
@on_requeue_error.call(cumulative_delay, current_requeue_number)
|
206
206
|
end
|
207
207
|
end
|
208
208
|
|
@@ -218,8 +218,8 @@ module Smith
|
|
218
218
|
delay * (current_requeue_number + 1)
|
219
219
|
end
|
220
220
|
|
221
|
-
def
|
222
|
-
@receiver.
|
221
|
+
def denormalized_queue_name
|
222
|
+
@receiver.denormalized_queue_name
|
223
223
|
end
|
224
224
|
|
225
225
|
def normalised_queue_name
|