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.
Files changed (54) hide show
  1. data/README +128 -0
  2. data/Rakefile +15 -0
  3. data/amqp.gemspec +83 -0
  4. data/amqp.todo +32 -0
  5. data/doc/EXAMPLE_01_PINGPONG +2 -0
  6. data/doc/EXAMPLE_02_CLOCK +2 -0
  7. data/doc/EXAMPLE_03_STOCKS +2 -0
  8. data/doc/EXAMPLE_04_MULTICLOCK +2 -0
  9. data/doc/EXAMPLE_05_ACK +2 -0
  10. data/doc/EXAMPLE_05_POP +2 -0
  11. data/doc/EXAMPLE_06_HASHTABLE +2 -0
  12. data/examples/amqp/simple.rb +79 -0
  13. data/examples/mq/ack.rb +45 -0
  14. data/examples/mq/clock.rb +56 -0
  15. data/examples/mq/hashtable.rb +52 -0
  16. data/examples/mq/internal.rb +49 -0
  17. data/examples/mq/logger.rb +88 -0
  18. data/examples/mq/multiclock.rb +49 -0
  19. data/examples/mq/pingpong.rb +45 -0
  20. data/examples/mq/pop.rb +43 -0
  21. data/examples/mq/primes-simple.rb +19 -0
  22. data/examples/mq/primes.rb +99 -0
  23. data/examples/mq/stocks.rb +58 -0
  24. data/lib/amqp.rb +115 -0
  25. data/lib/amqp/buffer.rb +395 -0
  26. data/lib/amqp/client.rb +210 -0
  27. data/lib/amqp/frame.rb +124 -0
  28. data/lib/amqp/protocol.rb +212 -0
  29. data/lib/amqp/server.rb +99 -0
  30. data/lib/amqp/spec.rb +832 -0
  31. data/lib/ext/blankslate.rb +7 -0
  32. data/lib/ext/em.rb +51 -0
  33. data/lib/ext/emfork.rb +69 -0
  34. data/lib/mq.rb +823 -0
  35. data/lib/mq/exchange.rb +302 -0
  36. data/lib/mq/header.rb +33 -0
  37. data/lib/mq/logger.rb +89 -0
  38. data/lib/mq/queue.rb +433 -0
  39. data/lib/mq/rpc.rb +100 -0
  40. data/old/README +30 -0
  41. data/old/Rakefile +12 -0
  42. data/old/amqp-0.8.json +606 -0
  43. data/old/amqp_spec.rb +796 -0
  44. data/old/amqpc.rb +695 -0
  45. data/old/codegen.rb +148 -0
  46. data/protocol/amqp-0.8.json +617 -0
  47. data/protocol/amqp-0.8.xml +3908 -0
  48. data/protocol/codegen.rb +173 -0
  49. data/protocol/doc.txt +281 -0
  50. data/research/api.rb +88 -0
  51. data/research/primes-forked.rb +63 -0
  52. data/research/primes-processes.rb +135 -0
  53. data/research/primes-threaded.rb +49 -0
  54. 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"]
@@ -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