amqp 0.7.0.pre → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/CHANGELOG +8 -2
- data/CONTRIBUTORS +22 -0
- data/Gemfile +3 -3
- data/README.md +20 -11
- data/Rakefile +30 -6
- data/amqp.gemspec +1 -1
- data/bin/cleanify.rb +50 -0
- data/examples/amqp/simple.rb +6 -4
- data/examples/mq/ack.rb +8 -6
- data/examples/mq/automatic_binding_for_default_direct_exchange.rb +65 -0
- data/examples/mq/callbacks.rb +9 -1
- data/examples/mq/clock.rb +17 -17
- data/examples/mq/hashtable.rb +19 -10
- data/examples/mq/internal.rb +13 -11
- data/examples/mq/logger.rb +38 -36
- data/examples/mq/multiclock.rb +16 -7
- data/examples/mq/pingpong.rb +16 -7
- data/examples/mq/pop.rb +8 -6
- data/examples/mq/primes-simple.rb +2 -0
- data/examples/mq/primes.rb +7 -5
- data/examples/mq/stocks.rb +14 -5
- data/lib/amqp.rb +12 -8
- data/lib/amqp/buffer.rb +35 -158
- data/lib/amqp/client.rb +34 -22
- data/lib/amqp/frame.rb +8 -64
- data/lib/amqp/protocol.rb +21 -70
- data/lib/amqp/server.rb +11 -9
- data/lib/amqp/spec.rb +8 -6
- data/lib/amqp/version.rb +2 -0
- data/lib/ext/blankslate.rb +3 -1
- data/lib/ext/em.rb +2 -0
- data/lib/ext/emfork.rb +13 -11
- data/lib/mq.rb +253 -156
- data/lib/mq/collection.rb +6 -88
- data/lib/mq/exchange.rb +70 -13
- data/lib/mq/header.rb +12 -6
- data/lib/mq/logger.rb +9 -7
- data/lib/mq/queue.rb +42 -30
- data/lib/mq/rpc.rb +6 -4
- data/protocol/codegen.rb +20 -18
- data/research/api.rb +10 -46
- data/research/primes-forked.rb +9 -7
- data/research/primes-processes.rb +74 -72
- data/research/primes-threaded.rb +9 -7
- data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +61 -0
- data/spec/mq_helper.rb +70 -0
- data/spec/spec_helper.rb +84 -29
- data/spec/unit/amqp/buffer_spec.rb +178 -0
- data/spec/unit/amqp/client_spec.rb +472 -0
- data/spec/unit/amqp/frame_spec.rb +60 -0
- data/spec/unit/amqp/misc_spec.rb +123 -0
- data/spec/unit/amqp/protocol_spec.rb +53 -0
- data/spec/unit/mq/channel_close_spec.rb +15 -0
- data/spec/unit/mq/collection_spec.rb +129 -0
- data/spec/unit/mq/exchange_declaration_spec.rb +524 -0
- data/spec/unit/mq/misc_spec.rb +228 -0
- data/spec/unit/mq/mq_basic_spec.rb +39 -0
- data/spec/unit/mq/queue_declaration_spec.rb +97 -0
- data/spec/unit/mq/queue_spec.rb +71 -0
- metadata +33 -21
- data/Gemfile.lock +0 -16
- data/old/README +0 -30
- data/old/Rakefile +0 -12
- data/old/amqp-0.8.json +0 -606
- data/old/amqp_spec.rb +0 -796
- data/old/amqpc.rb +0 -695
- data/old/codegen.rb +0 -148
- data/spec/channel_close_spec.rb +0 -13
- data/spec/sync_async_spec.rb +0 -52
data/examples/mq/hashtable.rb
CHANGED
@@ -1,21 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
4
|
require 'mq'
|
3
5
|
|
4
|
-
AMQP.start(:host => 'localhost') do
|
6
|
+
AMQP.start(:host => 'localhost') do |connection|
|
5
7
|
|
6
|
-
|
8
|
+
# Send Connection.Close on Ctrl+C
|
9
|
+
trap(:INT) do
|
10
|
+
unless connection.closing?
|
11
|
+
connection.close { exit! }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def log(*args)
|
7
16
|
p args
|
8
17
|
end
|
9
18
|
|
10
19
|
# AMQP.logging = true
|
11
20
|
|
12
21
|
class HashTable < Hash
|
13
|
-
def get
|
22
|
+
def get(key)
|
14
23
|
log 'HashTable', :get, key
|
15
24
|
self[key]
|
16
25
|
end
|
17
|
-
|
18
|
-
def set
|
26
|
+
|
27
|
+
def set(key, value)
|
19
28
|
log 'HashTable', :set, key => value
|
20
29
|
self[key] = value
|
21
30
|
end
|
@@ -37,16 +46,16 @@ AMQP.start(:host => 'localhost') do
|
|
37
46
|
client.set(:one, 1)
|
38
47
|
client.keys do |res|
|
39
48
|
log 'client', :keys => res
|
40
|
-
AMQP.stop{ EM.stop }
|
49
|
+
AMQP.stop { EM.stop }
|
41
50
|
end
|
42
51
|
|
43
52
|
end
|
44
53
|
|
45
54
|
__END__
|
46
55
|
|
47
|
-
["HashTable", :set, {:now=>Thu Jul 17 21:04:53 -0700 2008}]
|
56
|
+
["HashTable", :set, {:now => Thu Jul 17 21:04:53 -0700 2008}]
|
48
57
|
["HashTable", :get, :now]
|
49
|
-
["HashTable", :set, {:one=>1}]
|
58
|
+
["HashTable", :set, {:one => 1}]
|
50
59
|
["HashTable", :keys]
|
51
|
-
["client", {:eql
|
52
|
-
["client", {:keys=>[:one, :now]}]
|
60
|
+
["client", {:eql? => true, :now => Thu Jul 17 21:04:53 -0700 2008}]
|
61
|
+
["client", {:keys => [:one, :now]}]
|
data/examples/mq/internal.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
4
|
require 'mq'
|
3
5
|
require 'pp'
|
@@ -6,7 +8,7 @@ EM.run do
|
|
6
8
|
|
7
9
|
# connect to the amqp server
|
8
10
|
connection = AMQP.connect(:host => 'localhost', :logging => false)
|
9
|
-
|
11
|
+
|
10
12
|
# open a channel on the AMQP connection
|
11
13
|
channel = MQ.new(connection)
|
12
14
|
|
@@ -25,9 +27,9 @@ EM.run do
|
|
25
27
|
# subscribe to messages in the queue
|
26
28
|
queue.subscribe do |headers, msg|
|
27
29
|
pp [:got, headers, msg]
|
28
|
-
connection.close{ EM.stop_event_loop }
|
30
|
+
connection.close { EM.stop_event_loop }
|
29
31
|
end
|
30
|
-
|
32
|
+
|
31
33
|
end
|
32
34
|
|
33
35
|
__END__
|
@@ -36,14 +38,14 @@ __END__
|
|
36
38
|
#<AMQP::Protocol::Header:0x1186270
|
37
39
|
@klass=AMQP::Protocol::Basic,
|
38
40
|
@properties=
|
39
|
-
{:priority=>0,
|
40
|
-
:exchange=>"all queues",
|
41
|
-
:consumer_tag=>"queue name",
|
42
|
-
:delivery_tag=>1,
|
43
|
-
:delivery_mode=>1,
|
44
|
-
:redelivered=>false,
|
45
|
-
:content_type=>"application/octet-stream",
|
46
|
-
:routing_key=>""},
|
41
|
+
{:priority => 0,
|
42
|
+
:exchange => "all queues",
|
43
|
+
:consumer_tag => "queue name",
|
44
|
+
:delivery_tag => 1,
|
45
|
+
:delivery_mode => 1,
|
46
|
+
:redelivered => false,
|
47
|
+
:content_type => "application/octet-stream",
|
48
|
+
:routing_key => ""},
|
47
49
|
@size=11,
|
48
50
|
@weight=0>,
|
49
51
|
"hello world"]
|
data/examples/mq/logger.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
4
|
require 'mq'
|
3
5
|
require 'mq/logger'
|
@@ -7,7 +9,7 @@ Logger = MQ::Logger
|
|
7
9
|
AMQP.start(:host => 'localhost') do
|
8
10
|
if ARGV[0] == 'server'
|
9
11
|
|
10
|
-
MQ.queue('logger').bind(MQ.fanout('logging', :durable => true)).subscribe{|msg|
|
12
|
+
MQ.queue('logger').bind(MQ.fanout('logging', :durable => true)).subscribe { |msg|
|
11
13
|
msg = Marshal.load(msg)
|
12
14
|
require 'pp'
|
13
15
|
pp(msg)
|
@@ -18,7 +20,7 @@ AMQP.start(:host => 'localhost') do
|
|
18
20
|
|
19
21
|
log = Logger.new
|
20
22
|
log.debug 'its working!'
|
21
|
-
|
23
|
+
|
22
24
|
log = Logger.new do |msg|
|
23
25
|
require 'pp'
|
24
26
|
pp msg
|
@@ -26,7 +28,7 @@ AMQP.start(:host => 'localhost') do
|
|
26
28
|
end
|
27
29
|
|
28
30
|
log.info '123'
|
29
|
-
log.debug [1,2,3]
|
31
|
+
log.debug [1, 2, 3]
|
30
32
|
log.debug :one => 1, :two => 2
|
31
33
|
log.error Exception.new('123')
|
32
34
|
|
@@ -37,7 +39,7 @@ AMQP.start(:host => 'localhost') do
|
|
37
39
|
log = Logger.new(:webserver, :timestamp, :hostname, &log.printer)
|
38
40
|
log.info 'Request for /', :GET, :session => 'abc'
|
39
41
|
|
40
|
-
AMQP.stop{ EM.stop }
|
42
|
+
AMQP.stop { EM.stop }
|
41
43
|
|
42
44
|
else
|
43
45
|
|
@@ -54,35 +56,35 @@ end
|
|
54
56
|
|
55
57
|
__END__
|
56
58
|
|
57
|
-
{:data=>"123", :timestamp=>1216846102, :severity
|
58
|
-
|
59
|
-
{:data=>[1, 2, 3], :timestamp=>1216846102, :severity
|
60
|
-
|
61
|
-
{:data=>
|
62
|
-
{:type
|
63
|
-
:timestamp=>1216846102,
|
64
|
-
:severity
|
65
|
-
|
66
|
-
{:data=>"123", :timestamp=>1216846102, :process_id=>1814, :severity
|
67
|
-
|
68
|
-
{:process=>
|
69
|
-
{:thread_id=>109440,
|
70
|
-
:process_id=>1814,
|
71
|
-
:process_name=>"/Users/aman/code/amqp/examples/logger.rb",
|
72
|
-
:process_parent_id=>1813},
|
73
|
-
:data=>"123",
|
74
|
-
:timestamp=>1216846102,
|
75
|
-
:severity
|
76
|
-
|
77
|
-
{:session=>"abc",
|
78
|
-
:data=>"login",
|
79
|
-
:timestamp=>1216846102,
|
80
|
-
:severity
|
81
|
-
:user=>123}
|
82
|
-
|
83
|
-
{:session=>"abc",
|
84
|
-
:tags=>[:webserver, :GET],
|
85
|
-
:data=>"Request for /",
|
86
|
-
:timestamp=>1216846102,
|
87
|
-
:severity
|
88
|
-
:hostname=>"gc"}
|
59
|
+
{:data => "123", :timestamp => 1216846102, :severity => :info}
|
60
|
+
|
61
|
+
{:data => [1, 2, 3], :timestamp => 1216846102, :severity => :debug}
|
62
|
+
|
63
|
+
{:data =>
|
64
|
+
{:type => :exception, :name => :Exception, :message => "123", :backtrace => nil},
|
65
|
+
:timestamp => 1216846102,
|
66
|
+
:severity => :error}
|
67
|
+
|
68
|
+
{:data => "123", :timestamp => 1216846102, :process_id => 1814, :severity => :info}
|
69
|
+
|
70
|
+
{:process =>
|
71
|
+
{:thread_id => 109440,
|
72
|
+
:process_id => 1814,
|
73
|
+
:process_name => "/Users/aman/code/amqp/examples/logger.rb",
|
74
|
+
:process_parent_id => 1813},
|
75
|
+
:data => "123",
|
76
|
+
:timestamp => 1216846102,
|
77
|
+
:severity => :info}
|
78
|
+
|
79
|
+
{:session => "abc",
|
80
|
+
:data => "login",
|
81
|
+
:timestamp => 1216846102,
|
82
|
+
:severity => :debug,
|
83
|
+
:user => 123}
|
84
|
+
|
85
|
+
{:session => "abc",
|
86
|
+
:tags => [:webserver, :GET],
|
87
|
+
:data => "Request for /",
|
88
|
+
:timestamp => 1216846102,
|
89
|
+
:severity => :info,
|
90
|
+
:hostname => "gc"}
|
data/examples/mq/multiclock.rb
CHANGED
@@ -1,30 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
4
|
require 'mq'
|
3
5
|
require 'time'
|
4
6
|
|
5
|
-
AMQP.start(:host => 'localhost') do
|
7
|
+
AMQP.start(:host => 'localhost') do |connection|
|
8
|
+
|
9
|
+
# Send Connection.Close on Ctrl+C
|
10
|
+
trap(:INT) do
|
11
|
+
unless connection.closing?
|
12
|
+
connection.close { exit! }
|
13
|
+
end
|
14
|
+
end
|
6
15
|
|
7
|
-
def log
|
16
|
+
def log(*args)
|
8
17
|
p args
|
9
18
|
end
|
10
19
|
|
11
20
|
#AMQP.logging = true
|
12
21
|
|
13
22
|
clock = MQ.new.headers('multiformat_clock')
|
14
|
-
EM.add_periodic_timer(1){
|
23
|
+
EM.add_periodic_timer(1) {
|
15
24
|
puts
|
16
25
|
|
17
26
|
time = Time.new
|
18
|
-
["iso8601","rfc2822"].each do |format|
|
27
|
+
["iso8601", "rfc2822"].each do |format|
|
19
28
|
formatted_time = time.send(format)
|
20
29
|
log :publish, format, formatted_time
|
21
30
|
clock.publish "#{formatted_time}", :headers => {"format" => format}
|
22
31
|
end
|
23
32
|
}
|
24
33
|
|
25
|
-
["iso8601","rfc2822"].each do |format|
|
34
|
+
["iso8601", "rfc2822"].each do |format|
|
26
35
|
amq = MQ.new
|
27
|
-
amq.queue(format.to_s).bind(amq.headers('multiformat_clock'), :arguments => {"format" => format}).subscribe{ |time|
|
36
|
+
amq.queue(format.to_s).bind(amq.headers('multiformat_clock'), :arguments => {"format" => format}).subscribe { |time|
|
28
37
|
log "received #{format}", time
|
29
38
|
}
|
30
39
|
end
|
@@ -46,4 +55,4 @@ __END__
|
|
46
55
|
[:publish, "iso8601", "2009-02-13T19:55:42-08:00"]
|
47
56
|
[:publish, "rfc2822", "Fri, 13 Feb 2009 19:55:42 -0800"]
|
48
57
|
["received iso8601", "2009-02-13T19:55:42-08:00"]
|
49
|
-
["received rfc2822", "Fri, 13 Feb 2009 19:55:42 -0800"]
|
58
|
+
["received rfc2822", "Fri, 13 Feb 2009 19:55:42 -0800"]
|
data/examples/mq/pingpong.rb
CHANGED
@@ -1,16 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
4
|
require 'mq'
|
3
5
|
|
4
|
-
AMQP.start(:host => 'localhost') do
|
6
|
+
AMQP.start(:host => 'localhost') do |connection|
|
7
|
+
|
8
|
+
# Send Connection.Close on Ctrl+C
|
9
|
+
trap(:INT) do
|
10
|
+
unless connection.closing?
|
11
|
+
connection.close { exit! }
|
12
|
+
end
|
13
|
+
end
|
5
14
|
|
6
|
-
def log
|
15
|
+
def log(*args)
|
7
16
|
p [ Time.now, *args ]
|
8
17
|
end
|
9
|
-
|
18
|
+
|
10
19
|
# AMQP.logging = true
|
11
20
|
|
12
21
|
amq = MQ.new
|
13
|
-
EM.add_periodic_timer(1){
|
22
|
+
EM.add_periodic_timer(1) {
|
14
23
|
puts
|
15
24
|
|
16
25
|
log :sending, 'ping'
|
@@ -18,13 +27,13 @@ AMQP.start(:host => 'localhost') do
|
|
18
27
|
}
|
19
28
|
|
20
29
|
amq = MQ.new
|
21
|
-
amq.queue('one').subscribe{ |msg|
|
30
|
+
amq.queue('one').subscribe { |msg|
|
22
31
|
log 'one', :received, msg, :sending, 'pong'
|
23
32
|
amq.queue('two').publish('pong')
|
24
33
|
}
|
25
|
-
|
34
|
+
|
26
35
|
amq = MQ.new
|
27
|
-
amq.queue('two').subscribe{ |msg|
|
36
|
+
amq.queue('two').subscribe { |msg|
|
28
37
|
log 'two', :received, msg
|
29
38
|
}
|
30
39
|
|
data/examples/mq/pop.rb
CHANGED
@@ -1,24 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
4
|
require 'mq'
|
3
5
|
require 'pp'
|
4
6
|
|
5
|
-
Signal.trap('INT') { AMQP.stop{ EM.stop } }
|
6
|
-
Signal.trap('TERM'){ AMQP.stop{ EM.stop } }
|
7
|
+
Signal.trap('INT') { AMQP.stop { EM.stop } }
|
8
|
+
Signal.trap('TERM') { AMQP.stop { EM.stop } }
|
7
9
|
|
8
10
|
AMQP.start do
|
9
11
|
queue = MQ.queue('awesome')
|
10
12
|
|
11
13
|
queue.publish('Totally rad 1')
|
12
14
|
queue.publish('Totally rad 2')
|
13
|
-
EM.add_timer(5){ queue.publish('Totally rad 3') }
|
15
|
+
EM.add_timer(5) { queue.publish('Totally rad 3') }
|
14
16
|
|
15
|
-
queue.pop{ |msg|
|
17
|
+
queue.pop { |msg|
|
16
18
|
unless msg
|
17
19
|
# queue was empty
|
18
20
|
p [Time.now, :queue_empty!]
|
19
21
|
|
20
22
|
# try again in 1 second
|
21
|
-
EM.add_timer(1){ queue.pop }
|
23
|
+
EM.add_timer(1) { queue.pop }
|
22
24
|
else
|
23
25
|
# process this message
|
24
26
|
p [Time.now, msg]
|
@@ -40,4 +42,4 @@ __END__
|
|
40
42
|
[Wed Oct 15 15:24:34 -0700 2008, :queue_empty!]
|
41
43
|
[Wed Oct 15 15:24:35 -0700 2008, "Totally rad 3"]
|
42
44
|
[Wed Oct 15 15:24:35 -0700 2008, :queue_empty!]
|
43
|
-
[Wed Oct 15 15:24:36 -0700 2008, :queue_empty!]
|
45
|
+
[Wed Oct 15 15:24:36 -0700 2008, :queue_empty!]
|
data/examples/mq/primes.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
4
|
require 'mq'
|
3
5
|
|
@@ -5,7 +7,7 @@ require 'mq'
|
|
5
7
|
MAX = 1000
|
6
8
|
|
7
9
|
# logging
|
8
|
-
def log
|
10
|
+
def log(*args)
|
9
11
|
p args
|
10
12
|
end
|
11
13
|
|
@@ -34,7 +36,7 @@ end
|
|
34
36
|
|
35
37
|
# use workers to check which numbers are prime
|
36
38
|
AMQP.start(:host => 'localhost') do
|
37
|
-
|
39
|
+
|
38
40
|
prime_checker = MQ.rpc('prime checker')
|
39
41
|
|
40
42
|
(10_000...(10_000+MAX)).each do |num|
|
@@ -43,7 +45,7 @@ AMQP.start(:host => 'localhost') do
|
|
43
45
|
prime_checker.is_prime?(num) { |is_prime|
|
44
46
|
log :prime?, num, is_prime
|
45
47
|
(@primes||=[]) << num if is_prime
|
46
|
-
|
48
|
+
|
47
49
|
if (@responses = (@responses || 0) + 1) == MAX
|
48
50
|
log :primes=, @primes
|
49
51
|
EM.stop_event_loop
|
@@ -51,7 +53,7 @@ AMQP.start(:host => 'localhost') do
|
|
51
53
|
}
|
52
54
|
|
53
55
|
end
|
54
|
-
|
56
|
+
|
55
57
|
end
|
56
58
|
|
57
59
|
__END__
|
@@ -62,7 +64,7 @@ Linux gc 2.6.24-ARCH #1 SMP PREEMPT Sun Mar 30 10:50:22 CEST 2008 x86_64 Intel(R
|
|
62
64
|
$ cat /proc/cpuinfo | grep processor | wc -l
|
63
65
|
4
|
64
66
|
|
65
|
-
$ time ruby primes-simple.rb
|
67
|
+
$ time ruby primes-simple.rb
|
66
68
|
|
67
69
|
real 0m16.055s
|
68
70
|
user 0m16.052s
|
data/examples/mq/stocks.rb
CHANGED
@@ -1,15 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
4
|
require 'mq'
|
3
5
|
|
4
|
-
AMQP.start(:host => 'localhost') do
|
6
|
+
AMQP.start(:host => 'localhost') do |connection|
|
7
|
+
|
8
|
+
# Send Connection.Close on Ctrl+C
|
9
|
+
trap(:INT) do
|
10
|
+
unless connection.closing?
|
11
|
+
connection.close { exit! }
|
12
|
+
end
|
13
|
+
end
|
5
14
|
|
6
|
-
def log
|
15
|
+
def log(*args)
|
7
16
|
p [ Time.now, *args ]
|
8
17
|
end
|
9
18
|
|
10
19
|
def publish_stock_prices
|
11
20
|
mq = MQ.new
|
12
|
-
EM.add_periodic_timer(1){
|
21
|
+
EM.add_periodic_timer(1) {
|
13
22
|
puts
|
14
23
|
|
15
24
|
{ :appl => 170+rand(1000)/100.0,
|
@@ -25,14 +34,14 @@ AMQP.start(:host => 'localhost') do
|
|
25
34
|
|
26
35
|
def watch_appl_stock
|
27
36
|
mq = MQ.new
|
28
|
-
mq.queue('apple stock').bind(mq.topic('stocks'), :key => 'usd.appl').subscribe{ |price|
|
37
|
+
mq.queue('apple stock').bind(mq.topic('stocks'), :key => 'usd.appl').subscribe { |price|
|
29
38
|
log 'apple stock', price
|
30
39
|
}
|
31
40
|
end
|
32
41
|
|
33
42
|
def watch_us_stocks
|
34
43
|
mq = MQ.new
|
35
|
-
mq.queue('us stocks').bind(mq.topic('stocks'), :key => 'usd.*').subscribe{ |info, price|
|
44
|
+
mq.queue('us stocks').bind(mq.topic('stocks'), :key => 'usd.*').subscribe { |info, price|
|
36
45
|
log 'us stock', info.routing_key, price
|
37
46
|
}
|
38
47
|
end
|