adamh-amqp 0.6.3.1
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/README +128 -0
- data/Rakefile +15 -0
- data/amqp.gemspec +83 -0
- data/amqp.todo +32 -0
- data/doc/EXAMPLE_01_PINGPONG +2 -0
- data/doc/EXAMPLE_02_CLOCK +2 -0
- data/doc/EXAMPLE_03_STOCKS +2 -0
- data/doc/EXAMPLE_04_MULTICLOCK +2 -0
- data/doc/EXAMPLE_05_ACK +2 -0
- data/doc/EXAMPLE_05_POP +2 -0
- data/doc/EXAMPLE_06_HASHTABLE +2 -0
- data/examples/amqp/simple.rb +79 -0
- data/examples/mq/ack.rb +45 -0
- data/examples/mq/clock.rb +56 -0
- data/examples/mq/hashtable.rb +52 -0
- data/examples/mq/internal.rb +49 -0
- data/examples/mq/logger.rb +88 -0
- data/examples/mq/multiclock.rb +49 -0
- data/examples/mq/pingpong.rb +45 -0
- data/examples/mq/pop.rb +43 -0
- data/examples/mq/primes-simple.rb +19 -0
- data/examples/mq/primes.rb +99 -0
- data/examples/mq/stocks.rb +58 -0
- data/lib/amqp.rb +115 -0
- data/lib/amqp/buffer.rb +395 -0
- data/lib/amqp/client.rb +210 -0
- data/lib/amqp/frame.rb +124 -0
- data/lib/amqp/protocol.rb +212 -0
- data/lib/amqp/server.rb +99 -0
- data/lib/amqp/spec.rb +832 -0
- data/lib/ext/blankslate.rb +7 -0
- data/lib/ext/em.rb +51 -0
- data/lib/ext/emfork.rb +69 -0
- data/lib/mq.rb +823 -0
- data/lib/mq/exchange.rb +302 -0
- data/lib/mq/header.rb +33 -0
- data/lib/mq/logger.rb +89 -0
- data/lib/mq/queue.rb +433 -0
- data/lib/mq/rpc.rb +100 -0
- data/old/README +30 -0
- data/old/Rakefile +12 -0
- data/old/amqp-0.8.json +606 -0
- data/old/amqp_spec.rb +796 -0
- data/old/amqpc.rb +695 -0
- data/old/codegen.rb +148 -0
- data/protocol/amqp-0.8.json +617 -0
- data/protocol/amqp-0.8.xml +3908 -0
- data/protocol/codegen.rb +173 -0
- data/protocol/doc.txt +281 -0
- data/research/api.rb +88 -0
- data/research/primes-forked.rb +63 -0
- data/research/primes-processes.rb +135 -0
- data/research/primes-threaded.rb +49 -0
- metadata +121 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
|
+
require 'mq'
|
3
|
+
|
4
|
+
AMQP.start(:host => 'localhost') do
|
5
|
+
|
6
|
+
def log *args
|
7
|
+
p args
|
8
|
+
end
|
9
|
+
|
10
|
+
# AMQP.logging = true
|
11
|
+
|
12
|
+
class HashTable < Hash
|
13
|
+
def get key
|
14
|
+
log 'HashTable', :get, key
|
15
|
+
self[key]
|
16
|
+
end
|
17
|
+
|
18
|
+
def set key, value
|
19
|
+
log 'HashTable', :set, key => value
|
20
|
+
self[key] = value
|
21
|
+
end
|
22
|
+
|
23
|
+
def keys
|
24
|
+
log 'HashTable', :keys
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
server = MQ.new.rpc('hash table node', HashTable.new)
|
30
|
+
|
31
|
+
client = MQ.new.rpc('hash table node')
|
32
|
+
client.set(:now, time = Time.now)
|
33
|
+
client.get(:now) do |res|
|
34
|
+
log 'client', :now => res, :eql? => res == time
|
35
|
+
end
|
36
|
+
|
37
|
+
client.set(:one, 1)
|
38
|
+
client.keys do |res|
|
39
|
+
log 'client', :keys => res
|
40
|
+
AMQP.stop{ EM.stop }
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
__END__
|
46
|
+
|
47
|
+
["HashTable", :set, {:now=>Thu Jul 17 21:04:53 -0700 2008}]
|
48
|
+
["HashTable", :get, :now]
|
49
|
+
["HashTable", :set, {:one=>1}]
|
50
|
+
["HashTable", :keys]
|
51
|
+
["client", {:eql?=>true, :now=>Thu Jul 17 21:04:53 -0700 2008}]
|
52
|
+
["client", {:keys=>[:one, :now]}]
|
@@ -0,0 +1,49 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
|
+
require 'mq'
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
EM.run do
|
6
|
+
|
7
|
+
# connect to the amqp server
|
8
|
+
connection = AMQP.connect(:host => 'localhost', :logging => false)
|
9
|
+
|
10
|
+
# open a channel on the AMQP connection
|
11
|
+
channel = MQ.new(connection)
|
12
|
+
|
13
|
+
# declare a queue on the channel
|
14
|
+
queue = MQ::Queue.new(channel, 'queue name')
|
15
|
+
|
16
|
+
# create a fanout exchange
|
17
|
+
exchange = MQ::Exchange.new(channel, :fanout, 'all queues')
|
18
|
+
|
19
|
+
# bind the queue to the exchange
|
20
|
+
queue.bind(exchange)
|
21
|
+
|
22
|
+
# publish a message to the exchange
|
23
|
+
exchange.publish('hello world')
|
24
|
+
|
25
|
+
# subscribe to messages in the queue
|
26
|
+
queue.subscribe do |headers, msg|
|
27
|
+
pp [:got, headers, msg]
|
28
|
+
connection.close{ EM.stop_event_loop }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
__END__
|
34
|
+
|
35
|
+
[:got,
|
36
|
+
#<AMQP::Protocol::Header:0x1186270
|
37
|
+
@klass=AMQP::Protocol::Basic,
|
38
|
+
@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=>""},
|
47
|
+
@size=11,
|
48
|
+
@weight=0>,
|
49
|
+
"hello world"]
|
@@ -0,0 +1,88 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
|
+
require 'mq'
|
3
|
+
require 'mq/logger'
|
4
|
+
|
5
|
+
Logger = MQ::Logger
|
6
|
+
|
7
|
+
AMQP.start(:host => 'localhost') do
|
8
|
+
if ARGV[0] == 'server'
|
9
|
+
|
10
|
+
MQ.queue('logger').bind(MQ.fanout('logging', :durable => true)).subscribe{|msg|
|
11
|
+
msg = Marshal.load(msg)
|
12
|
+
require 'pp'
|
13
|
+
pp(msg)
|
14
|
+
puts
|
15
|
+
}
|
16
|
+
|
17
|
+
elsif ARGV[0] == 'client'
|
18
|
+
|
19
|
+
log = Logger.new
|
20
|
+
log.debug 'its working!'
|
21
|
+
|
22
|
+
log = Logger.new do |msg|
|
23
|
+
require 'pp'
|
24
|
+
pp msg
|
25
|
+
puts
|
26
|
+
end
|
27
|
+
|
28
|
+
log.info '123'
|
29
|
+
log.debug [1,2,3]
|
30
|
+
log.debug :one => 1, :two => 2
|
31
|
+
log.error Exception.new('123')
|
32
|
+
|
33
|
+
log.info '123', :process_id => Process.pid
|
34
|
+
log.info '123', :process
|
35
|
+
log.debug 'login', :session => 'abc', :user => 123
|
36
|
+
|
37
|
+
log = Logger.new(:webserver, :timestamp, :hostname, &log.printer)
|
38
|
+
log.info 'Request for /', :GET, :session => 'abc'
|
39
|
+
|
40
|
+
AMQP.stop{ EM.stop }
|
41
|
+
|
42
|
+
else
|
43
|
+
|
44
|
+
puts
|
45
|
+
puts "#{$0} <client|server>"
|
46
|
+
puts " client: send logs to message queue"
|
47
|
+
puts " server: read logs from message queue"
|
48
|
+
puts
|
49
|
+
|
50
|
+
EM.stop
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
__END__
|
56
|
+
|
57
|
+
{:data=>"123", :timestamp=>1216846102, :severity=>:info}
|
58
|
+
|
59
|
+
{:data=>[1, 2, 3], :timestamp=>1216846102, :severity=>:debug}
|
60
|
+
|
61
|
+
{:data=>
|
62
|
+
{:type=>:exception, :name=>:Exception, :message=>"123", :backtrace=>nil},
|
63
|
+
:timestamp=>1216846102,
|
64
|
+
:severity=>:error}
|
65
|
+
|
66
|
+
{:data=>"123", :timestamp=>1216846102, :process_id=>1814, :severity=>:info}
|
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=>:info}
|
76
|
+
|
77
|
+
{:session=>"abc",
|
78
|
+
:data=>"login",
|
79
|
+
:timestamp=>1216846102,
|
80
|
+
:severity=>:debug,
|
81
|
+
:user=>123}
|
82
|
+
|
83
|
+
{:session=>"abc",
|
84
|
+
:tags=>[:webserver, :GET],
|
85
|
+
:data=>"Request for /",
|
86
|
+
:timestamp=>1216846102,
|
87
|
+
:severity=>:info,
|
88
|
+
:hostname=>"gc"}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
|
+
require 'mq'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
AMQP.start(:host => 'localhost') do
|
6
|
+
|
7
|
+
def log *args
|
8
|
+
p args
|
9
|
+
end
|
10
|
+
|
11
|
+
#AMQP.logging = true
|
12
|
+
|
13
|
+
clock = MQ.new.headers('multiformat_clock')
|
14
|
+
EM.add_periodic_timer(1){
|
15
|
+
puts
|
16
|
+
|
17
|
+
time = Time.new
|
18
|
+
["iso8601","rfc2822"].each do |format|
|
19
|
+
formatted_time = time.send(format)
|
20
|
+
log :publish, format, formatted_time
|
21
|
+
clock.publish "#{formatted_time}", :headers => {"format" => format}
|
22
|
+
end
|
23
|
+
}
|
24
|
+
|
25
|
+
["iso8601","rfc2822"].each do |format|
|
26
|
+
amq = MQ.new
|
27
|
+
amq.queue(format.to_s).bind(amq.headers('multiformat_clock'), :arguments => {"format" => format}).subscribe{ |time|
|
28
|
+
log "received #{format}", time
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
__END__
|
35
|
+
|
36
|
+
[:publish, "iso8601", "2009-02-13T19:55:40-08:00"]
|
37
|
+
[:publish, "rfc2822", "Fri, 13 Feb 2009 19:55:40 -0800"]
|
38
|
+
["received iso8601", "2009-02-13T19:55:40-08:00"]
|
39
|
+
["received rfc2822", "Fri, 13 Feb 2009 19:55:40 -0800"]
|
40
|
+
|
41
|
+
[:publish, "iso8601", "2009-02-13T19:55:41-08:00"]
|
42
|
+
[:publish, "rfc2822", "Fri, 13 Feb 2009 19:55:41 -0800"]
|
43
|
+
["received iso8601", "2009-02-13T19:55:41-08:00"]
|
44
|
+
["received rfc2822", "Fri, 13 Feb 2009 19:55:41 -0800"]
|
45
|
+
|
46
|
+
[:publish, "iso8601", "2009-02-13T19:55:42-08:00"]
|
47
|
+
[:publish, "rfc2822", "Fri, 13 Feb 2009 19:55:42 -0800"]
|
48
|
+
["received iso8601", "2009-02-13T19:55:42-08:00"]
|
49
|
+
["received rfc2822", "Fri, 13 Feb 2009 19:55:42 -0800"]
|
@@ -0,0 +1,45 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
|
+
require 'mq'
|
3
|
+
|
4
|
+
AMQP.start(:host => 'localhost') do
|
5
|
+
|
6
|
+
def log *args
|
7
|
+
p [ Time.now, *args ]
|
8
|
+
end
|
9
|
+
|
10
|
+
# AMQP.logging = true
|
11
|
+
|
12
|
+
amq = MQ.new
|
13
|
+
EM.add_periodic_timer(1){
|
14
|
+
puts
|
15
|
+
|
16
|
+
log :sending, 'ping'
|
17
|
+
amq.queue('one').publish('ping')
|
18
|
+
}
|
19
|
+
|
20
|
+
amq = MQ.new
|
21
|
+
amq.queue('one').subscribe{ |msg|
|
22
|
+
log 'one', :received, msg, :sending, 'pong'
|
23
|
+
amq.queue('two').publish('pong')
|
24
|
+
}
|
25
|
+
|
26
|
+
amq = MQ.new
|
27
|
+
amq.queue('two').subscribe{ |msg|
|
28
|
+
log 'two', :received, msg
|
29
|
+
}
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
__END__
|
34
|
+
|
35
|
+
[Sun Jul 20 03:52:24 -0700 2008, :sending, "ping"]
|
36
|
+
[Sun Jul 20 03:52:24 -0700 2008, "one", :received, "ping", :sending, "pong"]
|
37
|
+
[Sun Jul 20 03:52:24 -0700 2008, "two", :received, "pong"]
|
38
|
+
|
39
|
+
[Sun Jul 20 03:52:25 -0700 2008, :sending, "ping"]
|
40
|
+
[Sun Jul 20 03:52:25 -0700 2008, "one", :received, "ping", :sending, "pong"]
|
41
|
+
[Sun Jul 20 03:52:25 -0700 2008, "two", :received, "pong"]
|
42
|
+
|
43
|
+
[Sun Jul 20 03:52:26 -0700 2008, :sending, "ping"]
|
44
|
+
[Sun Jul 20 03:52:26 -0700 2008, "one", :received, "ping", :sending, "pong"]
|
45
|
+
[Sun Jul 20 03:52:26 -0700 2008, "two", :received, "pong"]
|
data/examples/mq/pop.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
|
+
require 'mq'
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
Signal.trap('INT') { AMQP.stop{ EM.stop } }
|
6
|
+
Signal.trap('TERM'){ AMQP.stop{ EM.stop } }
|
7
|
+
|
8
|
+
AMQP.start do
|
9
|
+
queue = MQ.queue('awesome')
|
10
|
+
|
11
|
+
queue.publish('Totally rad 1')
|
12
|
+
queue.publish('Totally rad 2')
|
13
|
+
EM.add_timer(5){ queue.publish('Totally rad 3') }
|
14
|
+
|
15
|
+
queue.pop{ |msg|
|
16
|
+
unless msg
|
17
|
+
# queue was empty
|
18
|
+
p [Time.now, :queue_empty!]
|
19
|
+
|
20
|
+
# try again in 1 second
|
21
|
+
EM.add_timer(1){ queue.pop }
|
22
|
+
else
|
23
|
+
# process this message
|
24
|
+
p [Time.now, msg]
|
25
|
+
|
26
|
+
# get the next message in the queue
|
27
|
+
queue.pop
|
28
|
+
end
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
__END__
|
33
|
+
|
34
|
+
[Wed Oct 15 15:24:30 -0700 2008, "Totally rad 1"]
|
35
|
+
[Wed Oct 15 15:24:30 -0700 2008, "Totally rad 2"]
|
36
|
+
[Wed Oct 15 15:24:30 -0700 2008, :queue_empty!]
|
37
|
+
[Wed Oct 15 15:24:31 -0700 2008, :queue_empty!]
|
38
|
+
[Wed Oct 15 15:24:32 -0700 2008, :queue_empty!]
|
39
|
+
[Wed Oct 15 15:24:33 -0700 2008, :queue_empty!]
|
40
|
+
[Wed Oct 15 15:24:34 -0700 2008, :queue_empty!]
|
41
|
+
[Wed Oct 15 15:24:35 -0700 2008, "Totally rad 3"]
|
42
|
+
[Wed Oct 15 15:24:35 -0700 2008, :queue_empty!]
|
43
|
+
[Wed Oct 15 15:24:36 -0700 2008, :queue_empty!]
|
@@ -0,0 +1,19 @@
|
|
1
|
+
MAX = 1000
|
2
|
+
|
3
|
+
class Fixnum
|
4
|
+
def prime?
|
5
|
+
('1' * self) !~ /^1?$|^(11+?)\1+$/
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class PrimeChecker
|
10
|
+
def is_prime? number
|
11
|
+
number.prime?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
prime_checker = PrimeChecker.new
|
16
|
+
|
17
|
+
(10_000...(10_000+MAX)).each do |n|
|
18
|
+
prime_checker.is_prime? n
|
19
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
2
|
+
require 'mq'
|
3
|
+
|
4
|
+
# check MAX numbers for prime-ness
|
5
|
+
MAX = 1000
|
6
|
+
|
7
|
+
# logging
|
8
|
+
def log *args
|
9
|
+
p args
|
10
|
+
end
|
11
|
+
|
12
|
+
# spawn workers
|
13
|
+
workers = ARGV[0] ? (Integer(ARGV[0]) rescue 1) : 1
|
14
|
+
AMQP.fork(workers) do
|
15
|
+
|
16
|
+
log MQ.id, :started
|
17
|
+
|
18
|
+
class Fixnum
|
19
|
+
def prime?
|
20
|
+
('1' * self) !~ /^1?$|^(11+?)\1+$/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class PrimeChecker
|
25
|
+
def is_prime? number
|
26
|
+
log "prime checker #{MQ.id}", :prime?, number
|
27
|
+
number.prime?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
MQ.rpc('prime checker', PrimeChecker.new)
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# use workers to check which numbers are prime
|
36
|
+
AMQP.start(:host => 'localhost') do
|
37
|
+
|
38
|
+
prime_checker = MQ.rpc('prime checker')
|
39
|
+
|
40
|
+
(10_000...(10_000+MAX)).each do |num|
|
41
|
+
log :checking, num
|
42
|
+
|
43
|
+
prime_checker.is_prime?(num) { |is_prime|
|
44
|
+
log :prime?, num, is_prime
|
45
|
+
(@primes||=[]) << num if is_prime
|
46
|
+
|
47
|
+
if (@responses = (@responses || 0) + 1) == MAX
|
48
|
+
log :primes=, @primes
|
49
|
+
EM.stop_event_loop
|
50
|
+
end
|
51
|
+
}
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
__END__
|
58
|
+
|
59
|
+
$ uname -a
|
60
|
+
Linux gc 2.6.24-ARCH #1 SMP PREEMPT Sun Mar 30 10:50:22 CEST 2008 x86_64 Intel(R) Xeon(R) CPU X3220 @ 2.40GHz GenuineIntel GNU/Linux
|
61
|
+
|
62
|
+
$ cat /proc/cpuinfo | grep processor | wc -l
|
63
|
+
4
|
64
|
+
|
65
|
+
$ time ruby primes-simple.rb
|
66
|
+
|
67
|
+
real 0m16.055s
|
68
|
+
user 0m16.052s
|
69
|
+
sys 0m0.000s
|
70
|
+
|
71
|
+
$ time ruby primes.rb 1 >/dev/null
|
72
|
+
|
73
|
+
real 0m18.278s
|
74
|
+
user 0m0.993s
|
75
|
+
sys 0m0.027s
|
76
|
+
|
77
|
+
$ time ruby primes.rb 2 >/dev/null
|
78
|
+
|
79
|
+
real 0m17.316s
|
80
|
+
user 0m0.967s
|
81
|
+
sys 0m0.053s
|
82
|
+
|
83
|
+
$ time ruby primes.rb 4 >/dev/null
|
84
|
+
|
85
|
+
real 0m8.229s
|
86
|
+
user 0m1.010s
|
87
|
+
sys 0m0.030s
|
88
|
+
|
89
|
+
$ time ruby primes.rb 8 >/dev/null
|
90
|
+
|
91
|
+
real 0m5.893s
|
92
|
+
user 0m1.023s
|
93
|
+
sys 0m0.050s
|
94
|
+
|
95
|
+
$ time ruby primes.rb 16 >/dev/null
|
96
|
+
|
97
|
+
real 0m5.601s
|
98
|
+
user 0m0.990s
|
99
|
+
sys 0m0.043s
|