amqp 0.5.2 → 0.5.3

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 CHANGED
@@ -1,4 +1,11 @@
1
- Simple AMQP driver for Ruby/EventMachine.
1
+ Simple AMQP driver for Ruby/EventMachine
2
+ (c) 2008 Aman Gupta (tmm1)
3
+
4
+ http://github.com/tmm1/amqp
5
+ http://rubyforge.org/projects/amqp
6
+ http://hopper.squarespace.com/blog/2008/7/22/simple-amqp-library-for-ruby.html
7
+ http://groups.google.com/group/ruby-amqp
8
+ http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2008-July/001417.html
2
9
 
3
10
  This library was tested primarily with RabbitMQ, although it should be compatible with any
4
11
  server implementing the AMQP 0-8 spec.
@@ -12,15 +19,17 @@ To use with RabbitMQ, first run the server:
12
19
 
13
20
  To get started, refer to the various bundled examples:
14
21
 
15
- ruby examples/pingpong.rb # 1-1 communication using amq.direct
16
- ruby examples/clock.rb # 1-N communication using amq.fanout
17
- ruby examples/stocks.rb # 1-subscriber communication using amq.topic
18
- ruby examples/hashtable.rb # simple async rpc layer
19
- ruby examples/primes.rb 4 # parallelized prime number generation
22
+ ruby examples/mq/simple.rb # low-level Queue/Exchange api
23
+ ruby examples/mq/pingpong.rb # 1-1 communication using amq.direct
24
+ ruby examples/mq/clock.rb # 1-N communication using amq.fanout
25
+ ruby examples/mq/stocks.rb # 1-subscriber communication using amq.topic
26
+ ruby examples/mq/hashtable.rb # simple async rpc layer
27
+ ruby examples/mq/primes.rb 4 # parallelized prime number generation
28
+ ruby examples/mq/logger.rb # simple logging api
20
29
 
21
30
  For more details into the lower level AMQP client API, run the simple client example:
22
31
 
23
- ruby examples/simple.rb
32
+ ruby examples/amqp/simple.rb # low-level AMQP api
24
33
 
25
34
  Or refer to protocol/doc.txt, which enumerates packets sent between a server and client
26
35
  during a typical session, in both binary and decoded formats.
@@ -36,32 +45,47 @@ The lib/amqp/spec.rb file is generated automatically based on the AMQP specifica
36
45
  This project was inspired by py-amqplib, rabbitmq, qpid and rubbyt.
37
46
  Special thanks to Dmitriy Samovskiy, Ben Hood and Tony Garnock-Jones.
38
47
 
39
- Other AMQP resources:
48
+ AMQP resources:
40
49
 
41
50
  Servers:
42
- RabbitMQ (Rabbit Technologies, Erlang/OTP, MPL) http://rabbitmq.com
43
- OpenAMP (iMatrix, C, GPL2) http://openamq.org
44
- ActiveMQ (Apache Foundation, Java, apache2) http://activemq.apache.org/
51
+ RabbitMQ (Rabbit Technologies, Erlang/OTP, MPL) - http://rabbitmq.com
52
+ ZeroMQ (iMatrix/FastMQ/Intel, C++, GPL3) - http://www.zeromq.org
53
+ OpenAMQ (iMatrix, C, GPL2) - http://openamq.org
54
+ ActiveMQ (Apache Foundation, Java, apache2) - http://activemq.apache.org/
45
55
 
46
- John O'Hara's article on the history of AMQP:
56
+ Steve Vinoski explains AMQP in his column, Towards Integration
57
+ http://steve.vinoski.net/pdf/IEEE-Advanced_Message_Queuing_Protocol.pdf
58
+
59
+ John O'Hara on the history of AMQP
47
60
  http://www.acmqueue.org/modules.php?name=Content&pa=showpage&pid=485
48
61
 
49
- Barry Pederson's py-amqplib:
62
+ ZeroMQ's analysis of the messaging technology market
63
+ http://www.zeromq.org/whitepapers:market-analysis
64
+
65
+ ZeroMQ's background to AMQP
66
+ http://www.zeromq.org/whitepapers:amqp-analysis
67
+
68
+ Barry Pederson's py-amqplib
50
69
  http://barryp.org/software/py-amqplib/
51
70
 
52
- Ben Hood's article on writing an AMQP client:
71
+ Ben Hood on writing an AMQP client
53
72
  http://hopper.squarespace.com/blog/2008/6/21/build-your-own-amqp-client.html
54
73
 
55
- Dmitriy Samovskiy's introduction to Ruby+QPid+RabbitMQ:
74
+ Dmitriy Samovskiy introduces Ruby + QPid + RabbitMQ
56
75
  http://somic-org.homelinux.org/blog/2008/06/24/ruby-amqp-rabbitmq-example/
57
76
 
58
- Ben Hood's AMQP client in AS3:
77
+ Ben Hood's as3-amqp
59
78
  http://github.com/0x6e6562/as3-amqp
79
+ http://hopper.squarespace.com/blog/2008/7/4/server-side-as3.html
80
+ http://hopper.squarespace.com/blog/2008/3/24/as3-amqp-client-first-cut.html
60
81
 
61
- RabbitMQ's protocol code generator:
82
+ RabbitMQ's protocol code generator
62
83
  http://hg.rabbitmq.com/rabbitmq-codegen/
63
84
 
64
- Jonahthan Conway's series on RabbitMQ and using it with Ruby/Merb:
85
+ Erlang Exchange presentation on the implementation of RabbitMQ
86
+ http://www.lshift.net/blog/2008/07/01/slides-from-our-erlang-exchange-talk
87
+
88
+ Jonathan Conway's series on RabbitMQ and using it with Ruby/Merb
65
89
  http://jaikoo.com/2008/3/20/daemonize-rabbitmq
66
90
  http://jaikoo.com/2008/3/14/oh-hai-rabbitmq
67
91
  http://jaikoo.com/2008/2/29/friday-round-up-2008-02-29
@@ -77,3 +101,9 @@ Messaging and distributed systems resources:
77
101
 
78
102
  Convenience Over Correctness
79
103
  http://steve.vinoski.net/pdf/IEEE-Convenience_Over_Correctness.pdf
104
+
105
+ Metaprotocol Taxonomy and Communications Patterns
106
+ http://hessian.caucho.com/doc/metaprotocol-taxonomy.xtp
107
+
108
+ Joe Armstrong on Erlang messaging vs RPC:
109
+ http://armstrongonsoftware.blogspot.com/2008/05/road-we-didnt-go-down.html
@@ -1,4 +1,4 @@
1
- $:.unshift File.dirname(__FILE__) + '/../lib'
1
+ $:.unshift File.dirname(__FILE__) + '/../../lib'
2
2
  require 'amqp'
3
3
 
4
4
  module SimpleClient
@@ -1,4 +1,4 @@
1
- $:.unshift File.dirname(__FILE__) + '/../lib'
1
+ $:.unshift File.dirname(__FILE__) + '/../../lib'
2
2
  require 'mq'
3
3
 
4
4
  EM.run{
@@ -1,4 +1,4 @@
1
- $:.unshift File.dirname(__FILE__) + '/../lib'
1
+ $:.unshift File.dirname(__FILE__) + '/../../lib'
2
2
  require 'mq'
3
3
 
4
4
  EM.run{
@@ -0,0 +1,139 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../../lib'
2
+ require 'mq'
3
+
4
+ class Logger
5
+ def initialize *args, &block
6
+ opts = args.pop if args.last.is_a? Hash
7
+ opts ||= {}
8
+ printer(block) if block
9
+ @log = []
10
+ @tags = ([:timestamp] + args).uniq
11
+ end
12
+
13
+ def log severity, *args
14
+ opts = args.pop if args.last.is_a? Hash and args.size != 1
15
+ opts ||= {}
16
+ data = args.shift
17
+
18
+ data = {:type => :exception,
19
+ :name => data.class.to_s.intern,
20
+ :backtrace => data.backtrace,
21
+ :message => data.message} if data.is_a? Exception
22
+
23
+ (@tags + args).each do |tag|
24
+ tag = tag.to_sym
25
+ case tag
26
+ when :timestamp
27
+ opts.update :timestamp => Time.now.to_i
28
+ when :hostname
29
+ @hostname ||= { :hostname => `hostname`.strip }
30
+ opts.update @hostname
31
+ when :process
32
+ @process_id ||= { :process_id => Process.pid,
33
+ :process_name => $0,
34
+ :process_parent_id => Process.ppid,
35
+ :thread_id => Thread.current.object_id }
36
+ opts.update :process => @process_id
37
+ else
38
+ (opts[:tags] ||= []) << tag
39
+ end
40
+ end
41
+
42
+ opts.update(:severity => severity,
43
+ :data => data)
44
+
45
+ print(opts)
46
+ MQ.queue('logger', :durable => true).publish(Marshal.dump(opts), :persistent => true)
47
+ opts
48
+ end
49
+ alias :method_missing :log
50
+
51
+ def print data = nil, &block
52
+ if block
53
+ @printer = block
54
+ elsif data.is_a? Proc
55
+ @printer = data
56
+ elsif @printer and data
57
+ @printer.call(data)
58
+ else
59
+ @printer
60
+ end
61
+ end
62
+ alias :printer :print
63
+ end
64
+
65
+ EM.run{
66
+ # AMQP.logging = true
67
+ # MQ.logging = true
68
+
69
+ if ARGV[0] == 'server'
70
+
71
+ MQ.queue('logger', :durable => true).subscribe{|msg|
72
+ msg = Marshal.load(msg)
73
+ require 'pp'
74
+ pp(msg)
75
+ puts
76
+ }
77
+
78
+ else
79
+
80
+ log = Logger.new
81
+ log.debug 'its working!'
82
+
83
+ log = Logger.new do |msg|
84
+ require 'pp'
85
+ pp msg
86
+ puts
87
+ end
88
+
89
+ log.info '123'
90
+ log.debug [1,2,3]
91
+ log.debug :one => 1, :two => 2
92
+ log.error Exception.new('123')
93
+
94
+ log.info '123', :process_id => Process.pid
95
+ log.info '123', :process
96
+ log.debug 'login', :session => 'abc', :user => 123
97
+
98
+ log = Logger.new(:webserver, :timestamp, :hostname, &log.printer)
99
+ log.info 'Request for /', :GET, :session => 'abc'
100
+
101
+ AMQP.stop
102
+
103
+ end
104
+ }
105
+
106
+ __END__
107
+
108
+ {:data=>"123", :timestamp=>1216846102, :severity=>:info}
109
+
110
+ {:data=>[1, 2, 3], :timestamp=>1216846102, :severity=>:debug}
111
+
112
+ {:data=>
113
+ {:type=>:exception, :name=>:Exception, :message=>"123", :backtrace=>nil},
114
+ :timestamp=>1216846102,
115
+ :severity=>:error}
116
+
117
+ {:data=>"123", :timestamp=>1216846102, :process_id=>1814, :severity=>:info}
118
+
119
+ {:process=>
120
+ {:thread_id=>109440,
121
+ :process_id=>1814,
122
+ :process_name=>"/Users/aman/code/amqp/examples/logger.rb",
123
+ :process_parent_id=>1813},
124
+ :data=>"123",
125
+ :timestamp=>1216846102,
126
+ :severity=>:info}
127
+
128
+ {:session=>"abc",
129
+ :data=>"login",
130
+ :timestamp=>1216846102,
131
+ :severity=>:debug,
132
+ :user=>123}
133
+
134
+ {:session=>"abc",
135
+ :tags=>[:webserver, :GET],
136
+ :data=>"Request for /",
137
+ :timestamp=>1216846102,
138
+ :severity=>:info,
139
+ :hostname=>"gc"}
@@ -1,4 +1,4 @@
1
- $:.unshift File.dirname(__FILE__) + '/../lib'
1
+ $:.unshift File.dirname(__FILE__) + '/../../lib'
2
2
  require 'mq'
3
3
 
4
4
  EM.run{
@@ -1,4 +1,4 @@
1
- $:.unshift File.dirname(__FILE__) + '/../lib'
1
+ $:.unshift File.dirname(__FILE__) + '/../../lib'
2
2
  require 'mq'
3
3
 
4
4
  # check MAX numbers for prime-ness
@@ -0,0 +1,41 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../../lib'
2
+ require 'mq'
3
+ require 'pp'
4
+
5
+ EM.run do
6
+
7
+ # open a channel on the AMQP connection
8
+ channel = MQ.new
9
+
10
+ # declare a queue on the channel
11
+ queue = MQ::Queue.new(channel, 'queue name')
12
+
13
+ # use the default fanout exchange
14
+ exchange = MQ::Exchange.new(channel, :fanout, 'all queues')
15
+
16
+ # bind the queue to the exchange
17
+ queue.bind(exchange)
18
+
19
+ # publish a message to the exchange
20
+ exchange.publish('hello world')
21
+
22
+ # subscribe to messages from the queue
23
+ queue.subscribe do |headers, msg|
24
+ pp [:got, headers, msg]
25
+ AMQP.stop
26
+ end
27
+
28
+ end
29
+
30
+ __END__
31
+
32
+ [:got,
33
+ #<AMQP::Protocol::Header:0x118a438
34
+ @klass=AMQP::Protocol::Basic,
35
+ @properties=
36
+ {:priority=>0,
37
+ :delivery_mode=>1,
38
+ :content_type=>"application/octet-stream"},
39
+ @size=11,
40
+ @weight=0>,
41
+ "hello world"]
@@ -1,4 +1,4 @@
1
- $:.unshift File.dirname(__FILE__) + '/../lib'
1
+ $:.unshift File.dirname(__FILE__) + '/../../lib'
2
2
  require 'mq'
3
3
 
4
4
  EM.run{
@@ -1,9 +1,11 @@
1
1
  module AMQP
2
+ VERSION = '0.5.3'
3
+
2
4
  DIR = File.expand_path(File.dirname(File.expand_path(__FILE__)))
3
-
4
5
  $:.unshift DIR
5
6
 
6
7
  require 'ext/em'
8
+ require 'ext/blankslate'
7
9
 
8
10
  %w[ buffer spec protocol frame client ].each do |file|
9
11
  require "amqp/#{file}"
@@ -12,5 +14,42 @@ module AMQP
12
14
  class << self
13
15
  @logging = false
14
16
  attr_accessor :logging
17
+ attr_reader :stopping
18
+ end
19
+
20
+ def self.settings
21
+ @settings ||= {
22
+ :user => 'guest',
23
+ :pass => 'guest',
24
+ :vhost => '/'
25
+ }
26
+ end
27
+
28
+ def self.start *args
29
+ @conn ||= Client.connect *args
30
+ end
31
+
32
+ def self.stop stop_reactor = true, &on_stop
33
+ if @conn
34
+ @conn.callback{ |c|
35
+ if c.channels.keys.any?
36
+ c.channels.each do |_, mq|
37
+ mq.close
38
+ end
39
+ else
40
+ c.close
41
+ end
42
+ }
43
+ @on_stop = proc{
44
+ @conn = nil
45
+ on_stop.call if on_stop
46
+ EM.stop_event_loop if stop_reactor
47
+ }
48
+ end
49
+ end
50
+
51
+ def self.stopped
52
+ @on_stop.call if @on_stop
53
+ @on_stop = nil
15
54
  end
16
55
  end
@@ -1,7 +1,8 @@
1
1
  require 'amqp/frame'
2
- require 'pp'
3
2
 
4
3
  module AMQP
4
+ class Error < Exception; end
5
+
5
6
  module BasicClient
6
7
  def process_frame frame
7
8
  if mq = channels[frame.channel]
@@ -16,10 +17,10 @@ module AMQP
16
17
  send Protocol::Connection::StartOk.new({:platform => 'Ruby/EventMachine',
17
18
  :product => 'AMQP',
18
19
  :information => 'http://github.com/tmm1/amqp',
19
- :version => '0.5.0'},
20
+ :version => VERSION},
20
21
  'AMQPLAIN',
21
- {:LOGIN => 'guest',
22
- :PASSWORD => 'guest'},
22
+ {:LOGIN => @settings[:user],
23
+ :PASSWORD => @settings[:pass]},
23
24
  'en_US')
24
25
 
25
26
  when Protocol::Connection::Tune
@@ -27,12 +28,18 @@ module AMQP
27
28
  :frame_max => 131072,
28
29
  :heartbeat => 0)
29
30
 
30
- send Protocol::Connection::Open.new(:virtual_host => '/',
31
+ send Protocol::Connection::Open.new(:virtual_host => @settings[:vhost],
31
32
  :capabilities => '',
32
33
  :insist => false)
33
34
 
34
35
  when Protocol::Connection::OpenOk
35
36
  @dfr.succeed(self)
37
+
38
+ when Protocol::Connection::Close
39
+ raise Error, "#{method.reply_text} in #{Protocol.classes[method.class_id].methods[method.method_id]}"
40
+
41
+ when Protocol::Connection::CloseOk
42
+ AMQP.stopped
36
43
  end
37
44
  end
38
45
  end
@@ -48,8 +55,9 @@ module AMQP
48
55
  end
49
56
 
50
57
  module Client
51
- def initialize dfr
58
+ def initialize dfr, opts = {}
52
59
  @dfr = dfr
60
+ @settings = opts
53
61
  extend AMQP.client
54
62
  end
55
63
 
@@ -70,8 +78,8 @@ module AMQP
70
78
  end
71
79
 
72
80
  def receive_data data
81
+ # log 'receive_data', data
73
82
  @buf << data
74
- log 'receive_data', data
75
83
 
76
84
  while frame = Frame.parse(@buf)
77
85
  log 'receive', frame
@@ -92,9 +100,16 @@ module AMQP
92
100
  send_data data.to_s
93
101
  end
94
102
 
95
- def send_data data
96
- log 'send_data', data
97
- super
103
+ # def send_data data
104
+ # log 'send_data', data
105
+ # super
106
+ # end
107
+
108
+ def close
109
+ send Protocol::Connection::Close.new(:reply_code => 200,
110
+ :reply_text => 'Goodbye',
111
+ :class_id => 0,
112
+ :method_id => 0)
98
113
  end
99
114
 
100
115
  def unbind
@@ -102,13 +117,14 @@ module AMQP
102
117
  end
103
118
 
104
119
  def self.connect opts = {}
120
+ opts = AMQP.settings.merge(opts)
105
121
  opts[:host] ||= 'localhost'
106
122
  opts[:port] ||= PORT
107
123
 
108
124
  dfr = EM::DefaultDeferrable.new
109
125
 
110
126
  EM.run{
111
- EM.connect opts[:host], opts[:port], self, dfr
127
+ EM.connect opts[:host], opts[:port], self, dfr, opts
112
128
  }
113
129
 
114
130
  dfr
@@ -118,16 +134,9 @@ module AMQP
118
134
 
119
135
  def log *args
120
136
  return unless AMQP.logging
137
+ require 'pp'
121
138
  pp args
122
139
  puts
123
140
  end
124
141
  end
125
-
126
- def self.start *args
127
- @conn ||= Client.connect *args
128
- end
129
- end
130
-
131
- if $0 == __FILE__
132
- AMQP.start
133
142
  end
@@ -23,6 +23,12 @@ module AMQP
23
23
  end
24
24
  end
25
25
 
26
+ def arguments
27
+ self.class.arguments.inject({}) do |hash, (type, name)|
28
+ hash.update name => instance_variable_get("@#{name}")
29
+ end
30
+ end
31
+
26
32
  def to_binary
27
33
  buf = Buffer.new
28
34
  buf.write :short, self.class.parent.id
@@ -116,8 +122,8 @@ module AMQP
116
122
  end
117
123
 
118
124
  def method_missing meth, *args, &blk
119
- @klass.properties.map{|_,name| name }.include?(meth) ? @properties[meth] :
120
- super
125
+ @properties.has_key?(meth) || @klass.properties.find{|_,name| name == meth } ? @properties[meth] :
126
+ super
121
127
  end
122
128
  end
123
129
 
@@ -0,0 +1,7 @@
1
+ unless defined?(BlankSlate)
2
+ class BlankSlate < BasicObject; end if defined?(BasicObject)
3
+
4
+ class BlankSlate
5
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
6
+ end
7
+ end
data/lib/mq.rb CHANGED
@@ -10,6 +10,8 @@ class MQ
10
10
  @logging = false
11
11
  attr_accessor :logging
12
12
  end
13
+
14
+ class Error < Exception; end
13
15
  end
14
16
 
15
17
  class MQ
@@ -35,6 +37,7 @@ class MQ
35
37
  when Frame::Body
36
38
  @body << frame.payload
37
39
  if @body.length >= @header.size
40
+ @header.properties.update(@method.arguments)
38
41
  @consumer.receive @header, @body
39
42
  @body = ''
40
43
  end
@@ -49,12 +52,30 @@ class MQ
49
52
 
50
53
  when Protocol::Access::RequestOk
51
54
  @ticket = method.ticket
55
+ callback{
56
+ send Protocol::Channel::Close.new(:reply_code => 200,
57
+ :reply_text => 'bye',
58
+ :method_id => 0,
59
+ :class_id => 0)
60
+ } if @closing
52
61
  succeed
53
62
 
54
63
  when Protocol::Basic::Deliver
64
+ @method = method
55
65
  @header = nil
56
66
  @body = ''
57
67
  @consumer = queues[ method.consumer_tag ]
68
+
69
+
70
+ when Protocol::Channel::Close
71
+ raise Error, "#{method.reply_text} in #{Protocol.classes[method.class_id].methods[method.method_id]}"
72
+
73
+ when Protocol::Channel::CloseOk
74
+ @closing = false
75
+ conn.callback{ |c|
76
+ c.channels.delete(@channel)
77
+ c.close unless c.channels.keys.any?
78
+ }
58
79
  end
59
80
  end
60
81
  end
@@ -83,12 +104,15 @@ class MQ
83
104
  rpcs[name] ||= RPC.new(self, name, obj)
84
105
  end
85
106
 
86
- private
87
-
88
- def log *args
89
- return unless MQ.logging
90
- pp args
91
- puts
107
+ def close
108
+ if @deferred_status == :succeeded
109
+ send Protocol::Channel::Close.new(:reply_code => 200,
110
+ :reply_text => 'bye',
111
+ :method_id => 0,
112
+ :class_id => 0)
113
+ else
114
+ @closing = true
115
+ end
92
116
  end
93
117
 
94
118
  # keep track of proxy objects
@@ -105,9 +129,18 @@ class MQ
105
129
  @rcps ||= {}
106
130
  end
107
131
 
132
+ private
133
+
134
+ def log *args
135
+ return unless MQ.logging
136
+ pp args
137
+ puts
138
+ end
139
+
108
140
  # create a class level connection on demand
109
141
 
110
142
  def connection
143
+ raise 'MQ can only be used within EM.run{}' unless EM.reactor_running?
111
144
  @@connection ||= AMQP.start
112
145
  end
113
146
  alias :conn :connection
@@ -5,6 +5,7 @@ class MQ
5
5
  def initialize mq, type, name, opts = {}
6
6
  @mq = mq
7
7
  @type, @name = type, name
8
+ @mq.exchanges[@name = name] ||= self
8
9
  @key = opts[:key]
9
10
 
10
11
  @mq.callback{
@@ -17,18 +18,16 @@ class MQ
17
18
 
18
19
  def publish data, opts = {}
19
20
  @mq.callback{
20
- EM.next_tick do
21
- @mq.send Protocol::Basic::Publish.new({ :exchange => name,
22
- :routing_key => opts.delete(:key) || @key }.merge(opts))
23
-
24
- data = data.to_s
21
+ @mq.send Protocol::Basic::Publish.new({ :exchange => name,
22
+ :routing_key => opts.delete(:key) || @key }.merge(opts))
23
+
24
+ data = data.to_s
25
25
 
26
- @mq.send Protocol::Header.new(Protocol::Basic,
27
- data.length, { :content_type => 'application/octet-stream',
28
- :delivery_mode => 1,
29
- :priority => 0 }.merge(opts))
30
- @mq.send Frame::Body.new(data)
31
- end
26
+ @mq.send Protocol::Header.new(Protocol::Basic,
27
+ data.length, { :content_type => 'application/octet-stream',
28
+ :delivery_mode => (opts.delete(:persistent) ? 2 : 1),
29
+ :priority => 0 }.merge(opts))
30
+ @mq.send Frame::Body.new(data)
32
31
  }
33
32
  self
34
33
  end
@@ -4,7 +4,7 @@ class MQ
4
4
 
5
5
  def initialize mq, name, opts = {}
6
6
  @mq = mq
7
- @name = name
7
+ @mq.queues[@name = name] ||= self
8
8
  @mq.callback{
9
9
  @mq.send Protocol::Queue::Declare.new({ :queue => name,
10
10
  :nowait => true }.merge(opts))
@@ -1,15 +1,8 @@
1
- unless defined?(BlankSlate)
2
- class BlankSlate < BasicObject; end if defined?(BasicObject)
3
-
4
- class BlankSlate
5
- instance_methods.each { |m| undef_method m unless m =~ /^__/ }
6
- end
7
- end
8
-
9
1
  class MQ
10
2
  class RPC < BlankSlate
11
3
  def initialize mq, queue, obj = nil
12
4
  @mq = mq
5
+ @mq.rpcs[queue] ||= self
13
6
 
14
7
  if obj
15
8
  @obj = case obj
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amqp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aman Gupta
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-07-22 00:00:00 -07:00
12
+ date: 2008-07-29 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,19 +32,22 @@ extra_rdoc_files: []
32
32
 
33
33
  files:
34
34
  - README
35
- - examples/clock.rb
36
- - examples/hashtable.rb
37
- - examples/pingpong.rb
38
- - examples/primes-simple.rb
39
- - examples/primes.rb
40
- - examples/simple.rb
41
- - examples/stocks.rb
35
+ - examples/amqp/simple.rb
36
+ - examples/mq/clock.rb
37
+ - examples/mq/hashtable.rb
38
+ - examples/mq/logger.rb
39
+ - examples/mq/pingpong.rb
40
+ - examples/mq/primes-simple.rb
41
+ - examples/mq/primes.rb
42
+ - examples/mq/simple.rb
43
+ - examples/mq/stocks.rb
42
44
  - lib/amqp/buffer.rb
43
45
  - lib/amqp/client.rb
44
46
  - lib/amqp/frame.rb
45
47
  - lib/amqp/protocol.rb
46
48
  - lib/amqp/spec.rb
47
49
  - lib/amqp.rb
50
+ - lib/ext/blankslate.rb
48
51
  - lib/ext/em.rb
49
52
  - lib/ext/emfork.rb
50
53
  - lib/mq/exchange.rb