amqp 0.7.5 → 0.8.0.beta1
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/.gitignore +3 -4
- data/.travis.yml +3 -5
- data/.yardopts +6 -0
- data/CHANGELOG +26 -7
- data/Gemfile +15 -7
- data/README.textile +216 -0
- data/Rakefile +0 -6
- data/amqp.gemspec +14 -4
- data/bin/jenkins.sh +27 -0
- data/bin/set_test_suite_realms_up.sh +16 -2
- data/docs/VendorSpecificExtensions.textile +32 -0
- data/examples/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +53 -0
- data/examples/hello_world.rb +29 -0
- data/examples/real-world/task-queue/README.textile +3 -0
- data/examples/real-world/task-queue/consumer.rb +27 -0
- data/examples/real-world/task-queue/producer.rb +22 -0
- data/examples/various/ack.rb +70 -0
- data/examples/various/automatic_binding_for_default_direct_exchange.rb +53 -0
- data/examples/various/basic_get.rb +65 -0
- data/examples/various/callbacks.rb +45 -0
- data/examples/various/clock.rb +74 -0
- data/examples/various/declare_a_queue_without_assignment.rb +46 -0
- data/examples/various/declare_an_exchange_without_assignment.rb +46 -0
- data/examples/various/hashtable.rb +60 -0
- data/examples/{logger.rb → various/logger.rb} +9 -7
- data/examples/{multiclock.rb → various/multiclock.rb} +15 -17
- data/examples/various/open_channel_without_assignment.rb +34 -0
- data/examples/various/pingpong.rb +53 -0
- data/examples/various/primes-simple.rb +29 -0
- data/examples/various/primes.rb +76 -0
- data/examples/various/pubsub.rb +43 -0
- data/examples/various/queue_status.rb +58 -0
- data/examples/various/stocks.rb +59 -0
- data/examples/various/weather_updates.rb +63 -0
- data/lib/amqp.rb +11 -2
- data/lib/amqp/basic_client.rb +23 -54
- data/lib/amqp/channel.rb +577 -805
- data/lib/amqp/client.rb +37 -275
- data/lib/amqp/connection.rb +165 -93
- data/lib/amqp/deprecated/fork.rb +15 -0
- data/lib/amqp/deprecated/logger.rb +99 -0
- data/lib/amqp/deprecated/mq.rb +20 -0
- data/lib/amqp/deprecated/rpc.rb +168 -0
- data/lib/amqp/exchange.rb +409 -281
- data/lib/amqp/extensions/rabbitmq.rb +1 -0
- data/lib/amqp/header.rb +41 -17
- data/lib/amqp/logger.rb +10 -84
- data/lib/amqp/queue.rb +457 -320
- data/lib/amqp/rpc.rb +11 -107
- data/lib/amqp/version.rb +1 -1
- data/lib/mq.rb +2 -1
- data/lib/mq/logger.rb +2 -0
- data/lib/mq/rpc.rb +2 -0
- data/spec/integration/authentication_spec.rb +36 -40
- data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +3 -5
- data/spec/integration/basic_get_spec.rb +91 -0
- data/spec/integration/channel_close_spec.rb +5 -5
- data/spec/integration/exchange_declaration_spec.rb +6 -53
- data/spec/integration/extensions/basic_return_spec.rb +47 -0
- data/spec/integration/queue_declaration_spec.rb +14 -17
- data/spec/integration/queue_exclusivity_spec.rb +49 -48
- data/spec/integration/reply_queue_communication_spec.rb +6 -4
- data/spec/integration/store_and_forward_spec.rb +9 -36
- data/spec/integration/topic_subscription_spec.rb +1 -1
- data/spec/integration/workload_distribution_spec.rb +1 -0
- data/spec/spec_helper.rb +69 -43
- data/spec/unit/amqp/connection_spec.rb +27 -23
- data/tasks.rb +11 -0
- metadata +124 -95
- data/README.md +0 -156
- data/TODO +0 -30
- data/amqp.pre.gemspec +0 -6
- data/examples/ack.rb +0 -47
- data/examples/automatic_binding_for_default_direct_exchange.rb +0 -65
- data/examples/callbacks.rb +0 -40
- data/examples/clock.rb +0 -65
- data/examples/default_channel.rb +0 -19
- data/examples/hashtable.rb +0 -61
- data/examples/immediately_bind_a_server_named_queue.rb +0 -38
- data/examples/internal.rb +0 -51
- data/examples/issues/issue_75.rb +0 -21
- data/examples/issues/issue_94.rb +0 -23
- data/examples/pingpong.rb +0 -54
- data/examples/pop.rb +0 -45
- data/examples/primes-simple.rb +0 -21
- data/examples/primes.rb +0 -101
- data/examples/simple.rb +0 -81
- data/examples/stocks.rb +0 -67
- data/gemfiles/eventmachine-pre +0 -24
- data/lib/amqp/buffer.rb +0 -272
- data/lib/amqp/collection.rb +0 -60
- data/lib/amqp/frame.rb +0 -68
- data/lib/amqp/protocol.rb +0 -163
- data/lib/amqp/server.rb +0 -101
- data/lib/amqp/spec.rb +0 -832
- data/protocol/amqp-0.8.json +0 -617
- data/protocol/amqp-0.8.xml +0 -3908
- data/protocol/codegen.rb +0 -175
- data/protocol/doc.txt +0 -281
- data/research/api.rb +0 -52
- data/research/primes-forked.rb +0 -65
- data/research/primes-processes.rb +0 -137
- data/research/primes-threaded.rb +0 -51
- data/spec/integration/queue_status_spec.rb +0 -44
- data/spec/unit/amqp/buffer_spec.rb +0 -178
- data/spec/unit/amqp/client_spec.rb +0 -102
- data/spec/unit/amqp/collection_spec.rb +0 -144
- data/spec/unit/amqp/frame_spec.rb +0 -60
- data/spec/unit/amqp/protocol_spec.rb +0 -51
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
require "bundler"
|
|
5
|
+
Bundler.setup
|
|
6
|
+
|
|
7
|
+
$:.unshift(File.expand_path("../../../../lib", __FILE__))
|
|
8
|
+
require 'amqp'
|
|
9
|
+
require "amqp/extensions/rabbitmq"
|
|
10
|
+
|
|
11
|
+
AMQP.start do |connection|
|
|
12
|
+
puts "Connected!"
|
|
13
|
+
AMQP::Channel.new(connection) do |channel|
|
|
14
|
+
puts "Channel #{channel.id} is now open"
|
|
15
|
+
|
|
16
|
+
channel.confirmations
|
|
17
|
+
channel.on_error do
|
|
18
|
+
puts "Oops, there is a channel-levle exceptions!"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
channel.confirm do |basic_ack|
|
|
23
|
+
puts "Received basic_ack: multiple = #{basic_ack.multiple}, delivery_tag = #{basic_ack.delivery_tag}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
x = channel.fanout("amq.fanout")
|
|
27
|
+
channel.queue("", :auto_delete => true) do |q|
|
|
28
|
+
puts "Declared a new server-named qeueue: #{q.name}"
|
|
29
|
+
|
|
30
|
+
q.bind(x, :no_ack => true).subscribe(:ack => true) do |header, payload|
|
|
31
|
+
puts "Received #{payload}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
EventMachine.add_timer(0.5) do
|
|
36
|
+
10.times do |i|
|
|
37
|
+
puts "Publishing message ##{i}"
|
|
38
|
+
x.publish("Message ##{i}")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
show_stopper = Proc.new {
|
|
44
|
+
AMQP.stop do
|
|
45
|
+
EM.stop
|
|
46
|
+
end
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
EM.add_timer(3, show_stopper)
|
|
51
|
+
Signal.trap('INT', show_stopper)
|
|
52
|
+
Signal.trap('TERM', show_stopper)
|
|
53
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
require "bundler"
|
|
5
|
+
Bundler.setup
|
|
6
|
+
|
|
7
|
+
$:.unshift(File.expand_path("../../lib", __FILE__))
|
|
8
|
+
|
|
9
|
+
require 'amqp'
|
|
10
|
+
|
|
11
|
+
EventMachine.run do
|
|
12
|
+
AMQP.connect(:host => 'localhost') do |connection|
|
|
13
|
+
puts "Connected to AMQP broker"
|
|
14
|
+
|
|
15
|
+
channel = AMQP::Channel.new(connection)
|
|
16
|
+
queue = channel.queue("amqpgem.examples.hello_world")
|
|
17
|
+
exchange = channel.default_exchange
|
|
18
|
+
|
|
19
|
+
queue.subscribe do |payload|
|
|
20
|
+
puts "Received a message: #{payload}. Disconnecting..."
|
|
21
|
+
|
|
22
|
+
connection.close {
|
|
23
|
+
EM.stop { exit }
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
exchange.publish "Hello, world!", :routing_key => queue.name
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# encoding: utf - 8
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../../../../lib", __FILE__)
|
|
4
|
+
|
|
5
|
+
require "amqp"
|
|
6
|
+
|
|
7
|
+
# Imagine we have for example 10 servers, on each of them runs this
|
|
8
|
+
# script, just the server_name variable will be different on each of them.
|
|
9
|
+
server_name = "server - 1"
|
|
10
|
+
|
|
11
|
+
AMQP.start do
|
|
12
|
+
amq = AMQP::Channel.new
|
|
13
|
+
|
|
14
|
+
# Tasks distribution has to be based on load on each clients rather
|
|
15
|
+
# than on the number of distributed messages. (The default behaviour
|
|
16
|
+
# is to dispatches every n - th message to the n - th consumer.
|
|
17
|
+
amq.prefetch(1)
|
|
18
|
+
|
|
19
|
+
# Acknowledgements are good for letting the server know
|
|
20
|
+
# that the task is finished. If the consumer doesn't send
|
|
21
|
+
# the acknowledgement, then the task is considered to be unfinished.
|
|
22
|
+
amq.queue(server_name).subscribe(:ack => true) do |h, message|
|
|
23
|
+
puts message
|
|
24
|
+
puts system(message)
|
|
25
|
+
h.ack
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# encoding: utf - 8
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../../../../lib", __FILE__)
|
|
4
|
+
|
|
5
|
+
require "amqp"
|
|
6
|
+
|
|
7
|
+
# Imagine the command is something
|
|
8
|
+
# CPU - intensive like image processing.
|
|
9
|
+
command = "sleep 0.1"
|
|
10
|
+
|
|
11
|
+
AMQP.start(port: 1112) do
|
|
12
|
+
amq = AMQP::Channel.new
|
|
13
|
+
exchange = amq.direct("tasks")
|
|
14
|
+
queue = amq.queue("tasks")
|
|
15
|
+
|
|
16
|
+
# And this is user - input simulation,
|
|
17
|
+
# which can be a user uploading an image.
|
|
18
|
+
EM.add_periodic_timer(1) do
|
|
19
|
+
puts "~ publishing # {command}"
|
|
20
|
+
exchange.publish(command, :routing_key => "tasks")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
require "bundler"
|
|
5
|
+
Bundler.setup
|
|
6
|
+
|
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
|
8
|
+
require 'amqp'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
AMQP.start do |connection|
|
|
12
|
+
puts "Connected!"
|
|
13
|
+
channel = AMQP::Channel.new(connection)
|
|
14
|
+
e = channel.fanout("amqp-gem.examples.ack")
|
|
15
|
+
q = channel.queue('amqp-gem.examples.q1').bind(e) { puts "Bound #{e.name} to the queue" }
|
|
16
|
+
|
|
17
|
+
q.status do |message_count, consumer_count|
|
|
18
|
+
puts "Queue #{q.name} has #{message_count} messages and #{consumer_count} consumers"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
i = 0
|
|
22
|
+
|
|
23
|
+
# Stopping after the second item was acked will keep the 3rd item in the queue
|
|
24
|
+
q.subscribe(:ack => true) do |h, m|
|
|
25
|
+
puts "Got a message"
|
|
26
|
+
|
|
27
|
+
if AMQP.closing?
|
|
28
|
+
puts "#{m} (ignored, redelivered later)"
|
|
29
|
+
else
|
|
30
|
+
puts m
|
|
31
|
+
h.ack
|
|
32
|
+
end
|
|
33
|
+
end # channel.queue
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
10.times do |i|
|
|
37
|
+
puts "Publishing message ##{i}"
|
|
38
|
+
e.publish("Totally rad #{i}")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
show_stopper = Proc.new {
|
|
43
|
+
q.status do |message_count, consumer_count|
|
|
44
|
+
puts "Queue #{q.name} has #{message_count} messages and #{consumer_count} consumers"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
q.unbind(e) do
|
|
48
|
+
puts "Unbound #{q.name} from #{e.name}"
|
|
49
|
+
|
|
50
|
+
e.delete do
|
|
51
|
+
puts "Just deleted #{e.name}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
q.delete do
|
|
55
|
+
puts "Just deleted #{q.name}"
|
|
56
|
+
AMQP.stop do
|
|
57
|
+
puts "About to stop EM reactor"
|
|
58
|
+
EM.stop
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
EM.add_timer(3, show_stopper)
|
|
65
|
+
|
|
66
|
+
# For ack to work appropriately you must shutdown AMQP gracefully,
|
|
67
|
+
# otherwise all items in your queue will be returned
|
|
68
|
+
Signal.trap('INT', show_stopper)
|
|
69
|
+
Signal.trap('TERM', show_stopper)
|
|
70
|
+
end # AMQP.start
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
require "bundler"
|
|
5
|
+
Bundler.setup
|
|
6
|
+
|
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
|
8
|
+
|
|
9
|
+
require 'amqp'
|
|
10
|
+
|
|
11
|
+
if RUBY_VERSION == "1.8.7"
|
|
12
|
+
class Array
|
|
13
|
+
alias sample choice
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
puts "=> Default exchange example"
|
|
18
|
+
puts
|
|
19
|
+
AMQP.start(:host => 'localhost') do |connection|
|
|
20
|
+
ch = AMQP::Channel.new(connection)
|
|
21
|
+
|
|
22
|
+
queue1 = ch.queue("queue1").subscribe do |payload|
|
|
23
|
+
puts "[#{queue1.name}] => #{payload}"
|
|
24
|
+
end
|
|
25
|
+
queue2 = ch.queue("queue2").subscribe do |payload|
|
|
26
|
+
puts "[#{queue2.name}] => #{payload}"
|
|
27
|
+
end
|
|
28
|
+
queue3 = ch.queue("queue3").subscribe do |payload|
|
|
29
|
+
puts "[#{queue3.name}] => #{payload}"
|
|
30
|
+
end
|
|
31
|
+
queues = [queue1, queue2, queue3]
|
|
32
|
+
|
|
33
|
+
# Rely on default direct exchange binding, see section 2.1.2.4 Automatic Mode in AMQP 0.9.1 spec.
|
|
34
|
+
exchange = AMQP::Exchange.default
|
|
35
|
+
EM.add_periodic_timer(1) do
|
|
36
|
+
q = queues.sample
|
|
37
|
+
|
|
38
|
+
$stdout.puts "Publishing to default exchange with routing key = #{q.name}..."
|
|
39
|
+
exchange.publish "Some payload from #{Time.now.to_i}", :routing_key => q.name
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
show_stopper = Proc.new do
|
|
44
|
+
$stdout.puts "Stopping..."
|
|
45
|
+
connection.close {
|
|
46
|
+
EM.stop { exit }
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Signal.trap "INT", &show_stopper
|
|
51
|
+
Signal.trap "TERM", &show_stopper
|
|
52
|
+
EM.add_timer(7, show_stopper)
|
|
53
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
require "bundler"
|
|
5
|
+
Bundler.setup
|
|
6
|
+
|
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
|
8
|
+
|
|
9
|
+
require 'amqp'
|
|
10
|
+
|
|
11
|
+
if RUBY_VERSION == "1.8.7"
|
|
12
|
+
class Array
|
|
13
|
+
alias sample choice
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
puts "=> basic.get example"
|
|
19
|
+
puts
|
|
20
|
+
AMQP.start(:host => 'localhost') do |connection|
|
|
21
|
+
channel = AMQP::Channel.new
|
|
22
|
+
|
|
23
|
+
queue_name = "amqpgem.integration.basic.get.queue"
|
|
24
|
+
expected_number_of_messages = 50
|
|
25
|
+
|
|
26
|
+
exchange = channel.fanout("amqpgem.integration.basic.get.fanout", :auto_delete => true)
|
|
27
|
+
queue = channel.queue(queue_name, :auto_delete => true)
|
|
28
|
+
|
|
29
|
+
queue.bind(exchange) do
|
|
30
|
+
puts "Bound #{exchange.name} => #{queue.name}"
|
|
31
|
+
end
|
|
32
|
+
expected_number_of_messages.times do |i|
|
|
33
|
+
print "."
|
|
34
|
+
exchange.publish(Time.now.to_i.to_s + "_#{i}", :key => queue_name)
|
|
35
|
+
end
|
|
36
|
+
$stdout.flush
|
|
37
|
+
|
|
38
|
+
sleep 1
|
|
39
|
+
|
|
40
|
+
queue.status do |number_of_messages, number_of_consumers|
|
|
41
|
+
puts "# of messages on status = #{number_of_messages}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
queue.status do |number_of_messages, number_of_consumers|
|
|
45
|
+
puts "# of messages on status = #{number_of_messages}"
|
|
46
|
+
expected_number_of_messages.times do
|
|
47
|
+
queue.pop do |headers, payload|
|
|
48
|
+
puts "=> With payload #{payload.inspect}, routing key: #{headers.routing_key}, #{headers.message_count} message(s) left in the queue"
|
|
49
|
+
end # pop
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
show_stopper = Proc.new do
|
|
55
|
+
$stdout.puts "Stopping..."
|
|
56
|
+
# now change this to just EM.stop and it
|
|
57
|
+
# unbinds instantly
|
|
58
|
+
connection.close {
|
|
59
|
+
EM.stop { exit }
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
Signal.trap "INT", show_stopper
|
|
64
|
+
EM.add_timer(2, show_stopper)
|
|
65
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
require "bundler"
|
|
5
|
+
Bundler.setup
|
|
6
|
+
|
|
7
|
+
$:.unshift File.expand_path("../../lib", __FILE__)
|
|
8
|
+
require "amqp"
|
|
9
|
+
|
|
10
|
+
AMQP.start(:host => "localhost") do |connection|
|
|
11
|
+
|
|
12
|
+
# Send Connection.Close on Ctrl+C
|
|
13
|
+
trap(:INT) do
|
|
14
|
+
unless connection.closing?
|
|
15
|
+
connection.close { exit! }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
@counter = 0
|
|
20
|
+
amq = AMQP::Channel.new
|
|
21
|
+
|
|
22
|
+
amq.prefetch(64, false) do
|
|
23
|
+
puts "basic.qos callback has fired"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
amq.recover do
|
|
27
|
+
puts "basic.recover callback has fired"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
10.times do
|
|
31
|
+
amq.queue("") do |queue|
|
|
32
|
+
puts "Queue #{queue.name} is now declared."
|
|
33
|
+
puts "All queues: #{amq.queues.map { |q| q.name }.join(', ')}"
|
|
34
|
+
|
|
35
|
+
@counter += 1
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
EM.add_timer(0.3) do
|
|
40
|
+
connection.disconnect do
|
|
41
|
+
puts "AMQP connection is now closed."
|
|
42
|
+
EM.stop
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
require "bundler"
|
|
5
|
+
Bundler.setup
|
|
6
|
+
Bundler.require :default
|
|
7
|
+
|
|
8
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
|
9
|
+
require 'amqp'
|
|
10
|
+
|
|
11
|
+
puts "=> Clock example"
|
|
12
|
+
puts
|
|
13
|
+
AMQP.start(:host => 'localhost') do |connection|
|
|
14
|
+
puts "Connected!"
|
|
15
|
+
|
|
16
|
+
def log(*args)
|
|
17
|
+
p args
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# AMQP.logging = true
|
|
21
|
+
|
|
22
|
+
channel = AMQP::Channel.new(connection)
|
|
23
|
+
puts "Channel #{channel.id} is now open"
|
|
24
|
+
producer = channel.fanout('clock')
|
|
25
|
+
EM.add_periodic_timer(1) {
|
|
26
|
+
puts
|
|
27
|
+
|
|
28
|
+
log :publishing, time = Time.now
|
|
29
|
+
producer.publish(Marshal.dump(time))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
channel2 = AMQP::Channel.new(connection)
|
|
33
|
+
exchange = channel2.fanout('clock')
|
|
34
|
+
|
|
35
|
+
q1 = channel2.queue('every second')
|
|
36
|
+
q1.bind(exchange).subscribe(:confirm => proc { puts "Subscribed!" }) { |time|
|
|
37
|
+
log 'every second', :received, Marshal.load(time)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
puts "channel #{channel2.id} consumer tags: #{channel2.consumers.keys.join(', ')}"
|
|
41
|
+
|
|
42
|
+
# channel3 = AMQP::Channel.new
|
|
43
|
+
channel3 = AMQP::Channel.new(connection)
|
|
44
|
+
q2 = channel3.queue('every 5 seconds')
|
|
45
|
+
q2.bind(exchange).subscribe { |time|
|
|
46
|
+
time = Marshal.load(time)
|
|
47
|
+
log 'every 5 seconds', :received, time if time.strftime('%S').to_i % 5 == 0
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
show_stopper = Proc.new {
|
|
51
|
+
q1.unbind(exchange)
|
|
52
|
+
q2.unbind(exchange) do
|
|
53
|
+
puts "Unbound #{q2.name}."
|
|
54
|
+
|
|
55
|
+
q1.purge do |message_count|
|
|
56
|
+
puts "Purged #{q1.name}, there were #{message_count} messages"
|
|
57
|
+
puts "Deleting #{q1.name}…"
|
|
58
|
+
q1.delete(:if_empty => true, :nowait => true)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
q2.delete do |message_count|
|
|
62
|
+
puts "Deleted #{q2.name}. There were #{message_count} messages"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
puts " About to close AMQP connection…"
|
|
66
|
+
connection.close { exit! } unless connection.closing?
|
|
67
|
+
end
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Signal.trap "INT", show_stopper
|
|
71
|
+
Signal.trap "TERM", show_stopper
|
|
72
|
+
|
|
73
|
+
EM.add_timer(7, show_stopper)
|
|
74
|
+
end
|