amqp 0.9.10 → 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +0 -3
- data/CHANGELOG +4 -0
- data/Gemfile +1 -0
- data/README.md +72 -81
- data/amqp.gemspec +14 -5
- data/docs/08Migration.textile +0 -4
- data/docs/AMQP091ModelExplained.textile +0 -5
- data/docs/Bindings.textile +0 -4
- data/docs/Clustering.textile +0 -4
- data/docs/ConnectingToTheBroker.textile +1 -5
- data/docs/ConnectionEncryptionWithTLS.textile +0 -4
- data/docs/DocumentationGuidesIndex.textile +0 -4
- data/docs/Durability.textile +0 -4
- data/docs/ErrorHandling.textile +40 -106
- data/docs/Exchanges.textile +0 -4
- data/docs/GettingStarted.textile +6 -10
- data/docs/PatternsAndUseCases.textile +1 -4
- data/docs/Queues.textile +0 -4
- data/docs/RabbitMQVersions.textile +0 -4
- data/docs/RunningTests.textile +0 -4
- data/docs/TestingWithEventedSpec.textile +0 -4
- data/docs/Troubleshooting.textile +0 -4
- data/docs/VendorSpecificExtensions.textile +0 -4
- data/examples/error_handling/hello_world_producer.rb +1 -1
- data/examples/issues/issue_121.rb +23 -0
- data/examples/patterns/request_reply/client.rb +2 -1
- data/examples/patterns/request_reply/server.rb +1 -0
- data/examples/publishing/returned_messages.rb +1 -1
- data/lib/amqp.rb +0 -7
- data/lib/amqp/channel.rb +15 -33
- data/lib/amqp/client.rb +2 -2
- data/lib/amqp/compatibility/ruby187_patchlevel_check.rb +4 -4
- data/lib/amqp/connection.rb +0 -1
- data/lib/amqp/consumer.rb +2 -2
- data/lib/amqp/exceptions.rb +1 -10
- data/lib/amqp/exchange.rb +5 -5
- data/lib/amqp/queue.rb +23 -47
- data/lib/amqp/session.rb +4 -4
- data/lib/amqp/version.rb +1 -1
- data/spec/integration/basic_get_spec.rb +24 -80
- data/spec/integration/basic_return_spec.rb +3 -3
- data/spec/integration/channel_level_exception_with_multiple_channels_spec.rb +1 -0
- data/spec/integration/exchange_declaration_spec.rb +102 -71
- data/spec/integration/extensions/rabbitmq/publisher_confirmations_spec.rb +17 -1
- data/spec/integration/fanout_exchange_routing_spec.rb +1 -1
- data/spec/integration/immediate_messages_spec.rb +59 -0
- data/spec/integration/multiple_consumers_per_queue_spec.rb +101 -39
- data/spec/integration/queue_redeclaration_with_incompatible_attributes_spec.rb +12 -25
- data/spec/integration/regressions/concurrent_publishing_on_the_same_channel_spec.rb +1 -1
- data/spec/integration/reply_queue_communication_spec.rb +2 -1
- data/spec/integration/store_and_forward_spec.rb +9 -6
- data/spec/integration/topic_subscription_spec.rb +4 -5
- data/spec/spec_helper.rb +2 -8
- data/spec/unit/amqp/connection_spec.rb +1 -3
- metadata +112 -116
- data/examples/deprecated/default_thread_local_channel_instance.rb +0 -34
- data/examples/legacy/ack.rb +0 -70
- data/examples/legacy/callbacks.rb +0 -45
- data/examples/legacy/clock.rb +0 -74
- data/examples/legacy/hashtable.rb +0 -60
- data/examples/legacy/logger.rb +0 -92
- data/examples/legacy/multiclock.rb +0 -56
- data/examples/legacy/pingpong.rb +0 -51
- data/examples/legacy/primes-simple.rb +0 -29
- data/examples/legacy/primes.rb +0 -74
- data/examples/legacy/stocks.rb +0 -59
- data/lib/amqp/deprecated/fork.rb +0 -17
- data/lib/amqp/deprecated/logger.rb +0 -100
- data/lib/amqp/deprecated/mq.rb +0 -22
- data/lib/amqp/deprecated/rpc.rb +0 -169
- data/lib/amqp/ext/em.rb +0 -3
- data/lib/amqp/ext/emfork.rb +0 -72
- data/lib/amqp/logger.rb +0 -19
- data/lib/amqp/rpc.rb +0 -20
- data/lib/mq.rb +0 -35
- data/lib/mq/logger.rb +0 -4
- data/lib/mq/rpc.rb +0 -4
- data/spec/integration/remove_individual_binding_spec.rb +0 -51
data/examples/legacy/clock.rb
DELETED
@@ -1,74 +0,0 @@
|
|
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
|
@@ -1,60 +0,0 @@
|
|
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
|
-
def log(*args)
|
12
|
-
p args
|
13
|
-
end
|
14
|
-
|
15
|
-
# AMQP.logging = true
|
16
|
-
|
17
|
-
class HashTable < Hash
|
18
|
-
def get(key)
|
19
|
-
self[key]
|
20
|
-
end
|
21
|
-
|
22
|
-
def set(key, value)
|
23
|
-
self[key] = value
|
24
|
-
end
|
25
|
-
|
26
|
-
def keys
|
27
|
-
super
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
AMQP.start(:host => 'localhost') do |connection|
|
32
|
-
trap(:INT) do
|
33
|
-
unless connection.closing?
|
34
|
-
connection.close { exit! }
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
channel = AMQP::Channel.new(connection)
|
39
|
-
server = channel.rpc('hash table node', HashTable.new)
|
40
|
-
client = channel.rpc('hash table node')
|
41
|
-
|
42
|
-
client.set(:protocol, "amqp")
|
43
|
-
client.get(:protocol) do |res|
|
44
|
-
log 'client', :protocol_get_res => res
|
45
|
-
end
|
46
|
-
|
47
|
-
client.set(:now, time = Time.now)
|
48
|
-
client.get(:now) do |res|
|
49
|
-
log 'client', :now => res, :eql? => res == time
|
50
|
-
end
|
51
|
-
|
52
|
-
client.set(:one, 1)
|
53
|
-
client.keys do |res|
|
54
|
-
log 'client', :keys => res
|
55
|
-
end
|
56
|
-
|
57
|
-
EM.add_timer(3, Proc.new {
|
58
|
-
AMQP.stop { EM.stop }
|
59
|
-
})
|
60
|
-
end
|
data/examples/legacy/logger.rb
DELETED
@@ -1,92 +0,0 @@
|
|
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/logger'
|
10
|
-
|
11
|
-
AMQP.start(:host => 'localhost') do
|
12
|
-
if ARGV[0] == 'server'
|
13
|
-
|
14
|
-
AMQP::Channel.new.queue('logger').bind(AMQP::Channel.new.fanout('logging', :durable => true)).subscribe { |msg|
|
15
|
-
msg = Marshal.load(msg)
|
16
|
-
require 'pp'
|
17
|
-
pp(msg)
|
18
|
-
puts
|
19
|
-
}
|
20
|
-
|
21
|
-
elsif ARGV[0] == 'client'
|
22
|
-
|
23
|
-
log = AMQP::Logger.new
|
24
|
-
log.debug 'its working!'
|
25
|
-
|
26
|
-
log = AMQP::Logger.new do |msg|
|
27
|
-
require 'pp'
|
28
|
-
pp msg
|
29
|
-
puts
|
30
|
-
end
|
31
|
-
|
32
|
-
log.info '123'
|
33
|
-
log.debug [1, 2, 3]
|
34
|
-
log.debug :one => 1, :two => 2
|
35
|
-
log.error Exception.new('123')
|
36
|
-
|
37
|
-
log.info '123', :process_id => Process.pid
|
38
|
-
log.info '123', :process
|
39
|
-
log.debug 'login', :session => 'abc', :user => 123
|
40
|
-
|
41
|
-
log = AMQP::Logger.new(:webserver, :timestamp, :hostname, &log.printer)
|
42
|
-
log.info 'Request for /', :GET, :session => 'abc'
|
43
|
-
|
44
|
-
AMQP.stop { EM.stop }
|
45
|
-
|
46
|
-
else
|
47
|
-
|
48
|
-
puts
|
49
|
-
puts "#{$0} <client|server>"
|
50
|
-
puts " client: send logs to message queue"
|
51
|
-
puts " server: read logs from message queue"
|
52
|
-
puts
|
53
|
-
|
54
|
-
EM.stop
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
__END__
|
60
|
-
|
61
|
-
{:data => "123", :timestamp => 1216846102, :severity => :info}
|
62
|
-
|
63
|
-
{:data => [1, 2, 3], :timestamp => 1216846102, :severity => :debug}
|
64
|
-
|
65
|
-
{:data =>
|
66
|
-
{:type => :exception, :name => :Exception, :message => "123", :backtrace => nil},
|
67
|
-
:timestamp => 1216846102,
|
68
|
-
:severity => :error}
|
69
|
-
|
70
|
-
{:data => "123", :timestamp => 1216846102, :process_id => 1814, :severity => :info}
|
71
|
-
|
72
|
-
{:process =>
|
73
|
-
{:thread_id => 109440,
|
74
|
-
:process_id => 1814,
|
75
|
-
:process_name => "/Users/aman/code/amqp/examples/logger.rb",
|
76
|
-
:process_parent_id => 1813},
|
77
|
-
:data => "123",
|
78
|
-
:timestamp => 1216846102,
|
79
|
-
:severity => :info}
|
80
|
-
|
81
|
-
{:session => "abc",
|
82
|
-
:data => "login",
|
83
|
-
:timestamp => 1216846102,
|
84
|
-
:severity => :debug,
|
85
|
-
:user => 123}
|
86
|
-
|
87
|
-
{:session => "abc",
|
88
|
-
:tags => [:webserver, :GET],
|
89
|
-
:data => "Request for /",
|
90
|
-
:timestamp => 1216846102,
|
91
|
-
:severity => :info,
|
92
|
-
:hostname => "gc"}
|
@@ -1,56 +0,0 @@
|
|
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 'time'
|
10
|
-
|
11
|
-
AMQP.start(:host => 'localhost') do |connection|
|
12
|
-
|
13
|
-
# Send Connection.Close on Ctrl+C
|
14
|
-
trap(:INT) do
|
15
|
-
unless connection.closing?
|
16
|
-
connection.close { exit! }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def log(*args)
|
21
|
-
p args
|
22
|
-
end
|
23
|
-
|
24
|
-
#AMQP.logging = true
|
25
|
-
|
26
|
-
clock = AMQP::Channel.new.headers('multiformat_clock')
|
27
|
-
EM.add_periodic_timer(1) {
|
28
|
-
puts
|
29
|
-
|
30
|
-
time = Time.new
|
31
|
-
["iso8601", "rfc2822"].each do |format|
|
32
|
-
formatted_time = time.send(format)
|
33
|
-
log :publish, format, formatted_time
|
34
|
-
clock.publish "#{formatted_time}", :headers => {"format" => format} if connection.open?
|
35
|
-
end
|
36
|
-
}
|
37
|
-
|
38
|
-
["iso8601", "rfc2822"].each do |format|
|
39
|
-
amq = AMQP::Channel.new
|
40
|
-
amq.queue(format.to_s).bind(amq.headers('multiformat_clock'), :arguments => {"format" => format}).subscribe { |time|
|
41
|
-
log "received #{format}", time
|
42
|
-
}
|
43
|
-
end
|
44
|
-
|
45
|
-
show_stopper = Proc.new {
|
46
|
-
connection.close do
|
47
|
-
EM.stop
|
48
|
-
end
|
49
|
-
}
|
50
|
-
|
51
|
-
Signal.trap "INT", show_stopper
|
52
|
-
Signal.trap "TERM", show_stopper
|
53
|
-
|
54
|
-
EM.add_timer(3, show_stopper)
|
55
|
-
|
56
|
-
end
|
data/examples/legacy/pingpong.rb
DELETED
@@ -1,51 +0,0 @@
|
|
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
|
-
def log(*args)
|
12
|
-
p [ Time.now, *args ]
|
13
|
-
end
|
14
|
-
|
15
|
-
# AMQP.logging = true
|
16
|
-
|
17
|
-
amq = AMQP::Channel.new(connection)
|
18
|
-
exchange = amq.default_exchange
|
19
|
-
q1 = amq.queue('one')
|
20
|
-
q2 = amq.queue('two')
|
21
|
-
|
22
|
-
EM.add_periodic_timer(1) {
|
23
|
-
puts
|
24
|
-
|
25
|
-
log :sending, 'ping'
|
26
|
-
exchange.publish("ping", :routing_key => "one")
|
27
|
-
}
|
28
|
-
|
29
|
-
2.times do
|
30
|
-
q1.publish('ping', :routing_key => "one")
|
31
|
-
end
|
32
|
-
|
33
|
-
q1.subscribe do |msg|
|
34
|
-
log 'one', :received, msg, :sending, 'pong'
|
35
|
-
exchange.publish('pong', :routing_key => "two")
|
36
|
-
end
|
37
|
-
q2.subscribe { |msg| log('two', :received, msg) }
|
38
|
-
|
39
|
-
show_stopper = Proc.new do
|
40
|
-
$stdout.puts "Stopping..."
|
41
|
-
connection.close {
|
42
|
-
EM.stop { exit }
|
43
|
-
}
|
44
|
-
end
|
45
|
-
|
46
|
-
Signal.trap "INT", show_stopper
|
47
|
-
Signal.trap "TERM", show_stopper
|
48
|
-
|
49
|
-
EM.add_timer(3, show_stopper)
|
50
|
-
|
51
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
# You are probably wondering what the smeg is this example all about.
|
5
|
-
# Check examples/primes.rb, the only point of this file is to compare
|
6
|
-
# with its RPC implementation.
|
7
|
-
|
8
|
-
require "bundler"
|
9
|
-
Bundler.setup
|
10
|
-
|
11
|
-
MAX = 1000
|
12
|
-
|
13
|
-
class Fixnum
|
14
|
-
def prime?
|
15
|
-
('1' * self) !~ /^1?$|^(11+?)\1+$/
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class PrimeChecker
|
20
|
-
def is_prime?(number)
|
21
|
-
number.prime?
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
prime_checker = PrimeChecker.new
|
26
|
-
|
27
|
-
(10_000...(10_000 + MAX)).each do |n|
|
28
|
-
prime_checker.is_prime?(n)
|
29
|
-
end
|
data/examples/legacy/primes.rb
DELETED
@@ -1,74 +0,0 @@
|
|
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
|
-
# check MAX numbers for prime-ness
|
11
|
-
MAX = 1000
|
12
|
-
|
13
|
-
# logging
|
14
|
-
def log(*args)
|
15
|
-
p args
|
16
|
-
end
|
17
|
-
|
18
|
-
# spawn workers
|
19
|
-
workers = ARGV[0] ? (Integer(ARGV[0]) rescue 1) : 1
|
20
|
-
AMQP.fork(workers) do # TODO: AMQP.fork isn't implemented and I'm not sure if it should be implemented, it looks pretty damn ugly.
|
21
|
-
log AMQP::Channel.id, :started
|
22
|
-
|
23
|
-
class Fixnum
|
24
|
-
def prime?
|
25
|
-
('1' * self) !~ /^1?$|^(11+?)\1+$/
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class PrimeChecker
|
30
|
-
def is_prime? number
|
31
|
-
log "prime checker #{AMQP::Channel.id}", :prime?, number
|
32
|
-
number.prime?
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# This is the server part of RPC.
|
37
|
-
# Everything we'll call on the client part will be actually
|
38
|
-
# marshalled and published to a queue which the server part
|
39
|
-
# consumes and executes.
|
40
|
-
AMQP::Channel.new.rpc('prime checker', PrimeChecker.new)
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
# use workers to check which numbers are prime
|
45
|
-
AMQP.start(:host => 'localhost') do |connection|
|
46
|
-
|
47
|
-
show_stopper = Proc.new do
|
48
|
-
$stdout.puts "Stopping..."
|
49
|
-
connection.close {
|
50
|
-
EM.stop { exit }
|
51
|
-
}
|
52
|
-
end
|
53
|
-
|
54
|
-
prime_checker = AMQP::Channel.new.rpc('prime checker')
|
55
|
-
|
56
|
-
(10_000...(10_000 + MAX)).each do |num|
|
57
|
-
log :checking, num
|
58
|
-
|
59
|
-
prime_checker.is_prime?(num) { |is_prime|
|
60
|
-
log :prime?, num, is_prime
|
61
|
-
(@primes ||= []) << num if is_prime
|
62
|
-
|
63
|
-
if (@responses = (@responses || 0) + 1) == MAX
|
64
|
-
log :primes=, @primes
|
65
|
-
show_stopper.call
|
66
|
-
end
|
67
|
-
}
|
68
|
-
end
|
69
|
-
|
70
|
-
Signal.trap "INT", show_stopper
|
71
|
-
Signal.trap "TERM", show_stopper
|
72
|
-
|
73
|
-
EM.add_timer(5, show_stopper)
|
74
|
-
end
|
data/examples/legacy/stocks.rb
DELETED
@@ -1,59 +0,0 @@
|
|
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
|
-
def log(*args)
|
12
|
-
p [ Time.now, *args ]
|
13
|
-
end
|
14
|
-
|
15
|
-
AMQP::Channel.new(connection) do |ch, open_ok|
|
16
|
-
EM.add_periodic_timer(1) do
|
17
|
-
puts
|
18
|
-
|
19
|
-
{
|
20
|
-
:appl => 170 + rand(1000) / 100.0,
|
21
|
-
:msft => 22 + rand(500) / 100.0
|
22
|
-
}.each do |stock, price|
|
23
|
-
price = price.to_s
|
24
|
-
stock = "usd.#{stock}"
|
25
|
-
|
26
|
-
log :publishing, stock, price
|
27
|
-
ch.topic('stocks').publish(price, :key => stock) if connection.open?
|
28
|
-
end # each
|
29
|
-
end # add_periodic_timer
|
30
|
-
end # Channel.new
|
31
|
-
|
32
|
-
|
33
|
-
AMQP::Channel.new do |ch, open_ok|
|
34
|
-
ch.queue('apple stock').bind(ch.topic('stocks'), :key => 'usd.appl').subscribe { |price|
|
35
|
-
log 'apple stock', price
|
36
|
-
}
|
37
|
-
end
|
38
|
-
|
39
|
-
AMQP::Channel.new do |ch, open_ok|
|
40
|
-
ch.queue('us stocks').bind(ch.topic('stocks'), :key => 'usd.*').subscribe { |info, price|
|
41
|
-
log 'us stocks', info.routing_key, price
|
42
|
-
}
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
show_stopper = Proc.new {
|
48
|
-
connection.close do
|
49
|
-
puts "Connection is now closed properly"
|
50
|
-
EM.stop
|
51
|
-
end
|
52
|
-
}
|
53
|
-
|
54
|
-
Signal.trap "INT", show_stopper
|
55
|
-
Signal.trap "TERM", show_stopper
|
56
|
-
|
57
|
-
EM.add_timer(3, show_stopper)
|
58
|
-
|
59
|
-
end
|