fotonauts-amqp 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +128 -0
- data/Rakefile +15 -0
- data/amqp.gemspec +84 -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 +190 -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 +831 -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 +438 -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
|