bunny 0.4.4 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Rakefile +21 -3
  2. data/bunny.gemspec +34 -20
  3. data/examples/{simple.rb → simple_08.rb} +0 -0
  4. data/examples/simple_09.rb +30 -0
  5. data/examples/{simple_ack.rb → simple_ack_08.rb} +0 -0
  6. data/examples/simple_ack_09.rb +33 -0
  7. data/examples/{simple_consumer.rb → simple_consumer_08.rb} +0 -0
  8. data/examples/simple_consumer_09.rb +55 -0
  9. data/examples/{simple_fanout.rb → simple_fanout_08.rb} +0 -0
  10. data/examples/simple_fanout_09.rb +39 -0
  11. data/examples/{simple_headers.rb → simple_headers_08.rb} +0 -0
  12. data/examples/simple_headers_09.rb +40 -0
  13. data/examples/{simple_publisher.rb → simple_publisher_08.rb} +0 -0
  14. data/examples/simple_publisher_09.rb +27 -0
  15. data/examples/{simple_topic.rb → simple_topic_08.rb} +0 -0
  16. data/examples/simple_topic_09.rb +59 -0
  17. data/lib/bunny.rb +19 -14
  18. data/lib/bunny/channel08.rb +38 -0
  19. data/lib/bunny/channel09.rb +38 -0
  20. data/lib/bunny/client08.rb +167 -74
  21. data/lib/bunny/{client091.rb → client09.rb} +195 -92
  22. data/lib/bunny/{exchange091.rb → exchange09.rb} +12 -11
  23. data/lib/bunny/queue08.rb +1 -0
  24. data/lib/bunny/{queue091.rb → queue09.rb} +38 -28
  25. data/lib/qrack/client.rb +7 -0
  26. data/lib/qrack/protocol/{protocol.rb → protocol08.rb} +1 -4
  27. data/lib/qrack/protocol/protocol09.rb +133 -0
  28. data/lib/qrack/protocol/{spec091.rb → spec09.rb} +5 -5
  29. data/lib/qrack/qrack08.rb +2 -10
  30. data/lib/qrack/qrack09.rb +20 -0
  31. data/lib/qrack/transport/{buffer.rb → buffer08.rb} +0 -0
  32. data/lib/qrack/transport/buffer09.rb +276 -0
  33. data/lib/qrack/transport/{frame091.rb → frame09.rb} +8 -8
  34. data/spec/{bunny_spec.rb → spec_08/bunny_spec.rb} +4 -4
  35. data/spec/{exchange_spec.rb → spec_08/exchange_spec.rb} +3 -10
  36. data/spec/{queue_spec.rb → spec_08/queue_spec.rb} +1 -1
  37. data/spec/spec_09/bunny_spec.rb +40 -0
  38. data/spec/spec_09/exchange_spec.rb +131 -0
  39. data/spec/spec_09/queue_spec.rb +106 -0
  40. metadata +38 -22
  41. data/lib/qrack/qrack091.rb +0 -28
@@ -29,7 +29,7 @@ specification that applies to your target broker/server.
29
29
 
30
30
  =end
31
31
 
32
- class Exchange
32
+ class Exchange09
33
33
 
34
34
  attr_reader :client, :type, :name, :opts, :key
35
35
 
@@ -58,14 +58,15 @@ specification that applies to your target broker/server.
58
58
 
59
59
  unless name == "amq.#{type}" or name == ''
60
60
  client.send_frame(
61
- Qrack::Protocol::Exchange::Declare.new(
62
- { :exchange => name, :type => type, :nowait => false }.merge(opts)
61
+ Qrack::Protocol09::Exchange::Declare.new(
62
+ { :exchange => name, :type => type, :nowait => false,
63
+ :reserved_1 => 0, :reserved_2 => false, :reserved_3 => false }.merge(opts)
63
64
  )
64
65
  )
65
66
 
66
67
  raise Bunny::ProtocolError,
67
68
  "Error declaring exchange #{name}: type = #{type}" unless
68
- client.next_method.is_a?(Qrack::Protocol::Exchange::DeclareOk)
69
+ client.next_method.is_a?(Qrack::Protocol09::Exchange::DeclareOk)
69
70
  end
70
71
  end
71
72
 
@@ -98,19 +99,19 @@ nil
98
99
  def publish(data, opts = {})
99
100
  out = []
100
101
 
101
- out << Qrack::Protocol::Basic::Publish.new(
102
- { :exchange => name, :routing_key => opts.delete(:key) || key }.merge(opts)
102
+ out << Qrack::Protocol09::Basic::Publish.new(
103
+ { :exchange => name, :routing_key => opts.delete(:key) || key, :reserved_1 => 0 }.merge(opts)
103
104
  )
104
105
  data = data.to_s
105
- out << Qrack::Protocol::Header.new(
106
- Qrack::Protocol::Basic,
106
+ out << Qrack::Protocol09::Header.new(
107
+ Qrack::Protocol09::Basic,
107
108
  data.length, {
108
109
  :content_type => 'application/octet-stream',
109
110
  :delivery_mode => (opts.delete(:persistent) ? 2 : 1),
110
111
  :priority => 0
111
112
  }.merge(opts)
112
113
  )
113
- out << Qrack::Transport::Body.new(data)
114
+ out << Qrack::Transport09::Body.new(data)
114
115
 
115
116
  client.send_frame(*out)
116
117
  end
@@ -140,12 +141,12 @@ if successful. If an error occurs raises _Bunny_::_ProtocolError_.
140
141
  opts.delete(:nowait)
141
142
 
142
143
  client.send_frame(
143
- Qrack::Protocol::Exchange::Delete.new({ :exchange => name, :nowait => false }.merge(opts))
144
+ Qrack::Protocol09::Exchange::Delete.new({ :exchange => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
144
145
  )
145
146
 
146
147
  raise Bunny::ProtocolError,
147
148
  "Error deleting exchange #{name}" unless
148
- client.next_method.is_a?(Qrack::Protocol::Exchange::DeleteOk)
149
+ client.next_method.is_a?(Qrack::Protocol09::Exchange::DeleteOk)
149
150
 
150
151
  client.exchanges.delete(name)
151
152
 
data/lib/bunny/queue08.rb CHANGED
@@ -44,6 +44,7 @@ Queues must be attached to at least one exchange in order to receive messages fr
44
44
  raise Bunny::ProtocolError, "Error declaring queue #{name}" unless method.is_a?(Qrack::Protocol::Queue::DeclareOk)
45
45
 
46
46
  @name = method.queue
47
+ client.queues[@name] = self
47
48
  end
48
49
 
49
50
  =begin rdoc
@@ -9,7 +9,7 @@ Queues must be attached to at least one exchange in order to receive messages fr
9
9
 
10
10
  =end
11
11
 
12
- class Queue
12
+ class Queue09
13
13
  attr_reader :name, :client
14
14
  attr_accessor :delivery_tag
15
15
 
@@ -28,7 +28,8 @@ Queues must be attached to at least one exchange in order to receive messages fr
28
28
  :passive => false,
29
29
  :durable => false,
30
30
  :exclusive => true,
31
- :auto_delete => true
31
+ :auto_delete => true,
32
+ :reserved_1 => 0
32
33
  }.merge(opts)
33
34
  end
34
35
 
@@ -37,13 +38,14 @@ Queues must be attached to at least one exchange in order to receive messages fr
37
38
  opts.delete(:nowait)
38
39
 
39
40
  client.send_frame(
40
- Qrack::Protocol::Queue::Declare.new({ :queue => name || '', :nowait => false }.merge(opts))
41
+ Qrack::Protocol09::Queue::Declare.new({ :queue => name || '', :nowait => false, :reserved_1 => 0 }.merge(opts))
41
42
  )
42
43
 
43
44
  method = client.next_method
44
- raise Bunny::ProtocolError, "Error declaring queue #{name}" unless method.is_a?(Qrack::Protocol::Queue::DeclareOk)
45
+ raise Bunny::ProtocolError, "Error declaring queue #{name}" unless method.is_a?(Qrack::Protocol09::Queue::DeclareOk)
45
46
 
46
47
  @name = method.queue
48
+ client.queues[@name] = self
47
49
  end
48
50
 
49
51
  =begin rdoc
@@ -68,7 +70,7 @@ ask to confirm a single message or a set of messages up to and including a speci
68
70
  self.delivery_tag = 1 if self.delivery_tag.nil?
69
71
 
70
72
  client.send_frame(
71
- Qrack::Protocol::Basic::Ack.new({:delivery_tag => delivery_tag, :multiple => false}.merge(opts))
73
+ Qrack::Protocol09::Basic::Ack.new({:delivery_tag => delivery_tag, :multiple => false}.merge(opts))
72
74
  )
73
75
 
74
76
  # reset delivery tag
@@ -107,17 +109,18 @@ a hash <tt>{:delivery_tag, :redelivered, :exchange, :routing_key, :message_count
107
109
  ack = opts.delete(:ack)
108
110
 
109
111
  client.send_frame(
110
- Qrack::Protocol::Basic::Get.new({ :queue => name,
112
+ Qrack::Protocol09::Basic::Get.new({ :queue => name,
111
113
  :consumer_tag => name,
112
114
  :no_ack => !ack,
113
- :nowait => true }.merge(opts))
115
+ :nowait => true,
116
+ :reserved_1 => 0 }.merge(opts))
114
117
  )
115
118
 
116
119
  method = client.next_method
117
120
 
118
- if method.is_a?(Qrack::Protocol::Basic::GetEmpty) then
121
+ if method.is_a?(Qrack::Protocol09::Basic::GetEmpty) then
119
122
  return :queue_empty
120
- elsif !method.is_a?(Qrack::Protocol::Basic::GetOk)
123
+ elsif !method.is_a?(Qrack::Protocol09::Basic::GetOk)
121
124
  raise Bunny::ProtocolError, "Error getting message from queue #{name}"
122
125
  end
123
126
 
@@ -185,7 +188,7 @@ Returns hash {:message_count, :consumer_count}.
185
188
 
186
189
  def status
187
190
  client.send_frame(
188
- Qrack::Protocol::Queue::Declare.new({ :queue => name, :passive => true })
191
+ Qrack::Protocol09::Queue::Declare.new({ :queue => name, :passive => true, :reserved_1 => 0 })
189
192
  )
190
193
  method = client.next_method
191
194
  {:message_count => method.message_count, :consumer_count => method.consumer_count}
@@ -236,20 +239,21 @@ If <tt>:header => false</tt> only message payload is returned.
236
239
  ack = opts.delete(:ack)
237
240
 
238
241
  client.send_frame(
239
- Qrack::Protocol::Basic::Consume.new({ :queue => name,
240
- :consumer_tag => consumer_tag,
241
- :no_ack => !ack,
242
- :nowait => false }.merge(opts))
242
+ Qrack::Protocol09::Basic::Consume.new({ :reserved_1 => 0,
243
+ :queue => name,
244
+ :consumer_tag => consumer_tag,
245
+ :no_ack => !ack,
246
+ :nowait => false }.merge(opts))
243
247
  )
244
248
 
245
249
  raise Bunny::ProtocolError,
246
250
  "Error subscribing to queue #{name}" unless
247
- client.next_method.is_a?(Qrack::Protocol::Basic::ConsumeOk)
251
+ client.next_method.is_a?(Qrack::Protocol09::Basic::ConsumeOk)
248
252
 
249
253
  while true
250
254
  method = client.next_method
251
255
 
252
- break if method.is_a?(Qrack::Protocol::Basic::CancelOk)
256
+ break if method.is_a?(Qrack::Protocol09::Basic::CancelOk)
253
257
 
254
258
  # get delivery tag to use for acknowledge
255
259
  self.delivery_tag = method.delivery_tag if ack
@@ -285,7 +289,7 @@ the server will not send any more messages for that consumer.
285
289
  # response from the server causing an error
286
290
  opts.delete(:nowait)
287
291
 
288
- client.send_frame( Qrack::Protocol::Basic::Cancel.new({ :consumer_tag => consumer_tag }.merge(opts)))
292
+ client.send_frame( Qrack::Protocol09::Basic::Cancel.new({ :consumer_tag => consumer_tag }.merge(opts)))
289
293
 
290
294
  end
291
295
 
@@ -315,15 +319,16 @@ bound to the direct exchange '' by default. If error occurs, a _Bunny_::_Protoco
315
319
 
316
320
  bindings[exchange] = opts
317
321
  client.send_frame(
318
- Qrack::Protocol::Queue::Bind.new({ :queue => name,
322
+ Qrack::Protocol09::Queue::Bind.new({ :queue => name,
319
323
  :exchange => exchange,
320
324
  :routing_key => opts.delete(:key),
321
- :nowait => false }.merge(opts))
325
+ :nowait => false,
326
+ :reserved_1 => 0 }.merge(opts))
322
327
  )
323
328
 
324
329
  raise Bunny::ProtocolError,
325
330
  "Error binding queue #{name}" unless
326
- client.next_method.is_a?(Qrack::Protocol::Queue::BindOk)
331
+ client.next_method.is_a?(Qrack::Protocol09::Queue::BindOk)
327
332
 
328
333
  # return message
329
334
  :bind_ok
@@ -356,16 +361,17 @@ Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolE
356
361
  bindings.delete(exchange)
357
362
 
358
363
  client.send_frame(
359
- Qrack::Protocol::Queue::Unbind.new({ :queue => name,
364
+ Qrack::Protocol09::Queue::Unbind.new({ :queue => name,
360
365
  :exchange => exchange,
361
366
  :routing_key => opts.delete(:key),
362
- :nowait => false }.merge(opts)
367
+ :nowait => false,
368
+ :reserved_1 => 0 }.merge(opts)
363
369
  )
364
370
  )
365
371
 
366
372
  raise Bunny::ProtocolError,
367
373
  "Error unbinding queue #{name}" unless
368
- client.next_method.is_a?(Qrack::Protocol::Queue::UnbindOk)
374
+ client.next_method.is_a?(Qrack::Protocol09::Queue::UnbindOk)
369
375
 
370
376
  # return message
371
377
  :unbind_ok
@@ -400,12 +406,12 @@ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
400
406
  opts.delete(:nowait)
401
407
 
402
408
  client.send_frame(
403
- Qrack::Protocol::Queue::Delete.new({ :queue => name, :nowait => false }.merge(opts))
409
+ Qrack::Protocol09::Queue::Delete.new({ :queue => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
404
410
  )
405
411
 
406
412
  raise Bunny::ProtocolError,
407
413
  "Error deleting queue #{name}" unless
408
- client.next_method.is_a?(Qrack::Protocol::Queue::DeleteOk)
414
+ client.next_method.is_a?(Qrack::Protocol09::Queue::DeleteOk)
409
415
 
410
416
  client.queues.delete(name)
411
417
 
@@ -435,10 +441,10 @@ without any formal "undo" mechanism. If an error occurs raises _Bunny_::_Protoco
435
441
  opts.delete(:nowait)
436
442
 
437
443
  client.send_frame(
438
- Qrack::Protocol::Queue::Purge.new({ :queue => name, :nowait => false }.merge(opts))
444
+ Qrack::Protocol09::Queue::Purge.new({ :queue => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
439
445
  )
440
446
 
441
- raise Bunny::ProtocolError, "Error purging queue #{name}" unless client.next_method.is_a?(Qrack::Protocol::Queue::PurgeOk)
447
+ raise Bunny::ProtocolError, "Error purging queue #{name}" unless client.next_method.is_a?(Qrack::Protocol09::Queue::PurgeOk)
442
448
 
443
449
  # return confirmation
444
450
  :purge_ok
@@ -447,7 +453,11 @@ without any formal "undo" mechanism. If an error occurs raises _Bunny_::_Protoco
447
453
 
448
454
  private
449
455
  def exchange
450
- @exchange ||= Bunny::Exchange.new(client, '', {:type => :direct, :key => name})
456
+ @exchange ||= Bunny::Exchange09.new(client, '', { :type => :direct,
457
+ :key => name,
458
+ :reserved_1 => 0,
459
+ :reserved_2 => false,
460
+ :reserved_3 => false})
451
461
  end
452
462
 
453
463
  def bindings
data/lib/qrack/client.rb CHANGED
@@ -1,5 +1,12 @@
1
1
  module Qrack
2
2
  # Client ancestor class
3
3
  class Client
4
+
5
+ CONNECT_TIMEOUT = 1.0
6
+ RETRY_DELAY = 10.0
7
+
8
+ attr_reader :status, :host, :vhost, :port, :logging, :spec
9
+ attr_accessor :channel, :logfile, :exchanges, :queues, :channels
10
+
4
11
  end
5
12
  end
@@ -6,8 +6,6 @@ module Qrack
6
6
  opts = args.pop if args.last.is_a? Hash
7
7
  opts ||= {}
8
8
 
9
- @debug = 1 # XXX hack, p(obj) == '' if no instance vars are set
10
-
11
9
  if args.size == 1 and args.first.is_a? Transport::Buffer
12
10
  buf = args.shift
13
11
  else
@@ -120,8 +118,7 @@ module Qrack
120
118
  end
121
119
 
122
120
  def method_missing meth, *args, &blk
123
- @properties.has_key?(meth) || @klass.properties.find{|_,name| name == meth } ? @properties[meth] :
124
- super
121
+ @properties.has_key?(meth) || @klass.properties.find{|_,name| name == meth } ? @properties[meth] : super
125
122
  end
126
123
  end
127
124
 
@@ -0,0 +1,133 @@
1
+ module Qrack
2
+ module Protocol09
3
+ #:stopdoc:
4
+ class Class::Method
5
+ def initialize *args
6
+ opts = args.pop if args.last.is_a? Hash
7
+ opts ||= {}
8
+
9
+ if args.size == 1 and args.first.is_a? Transport09::Buffer
10
+ buf = args.shift
11
+ else
12
+ buf = nil
13
+ end
14
+
15
+ self.class.arguments.each do |type, name|
16
+ val = buf ? buf.read(type) :
17
+ args.shift || opts[name] || opts[name.to_s]
18
+ instance_variable_set("@#{name}", val)
19
+ end
20
+ end
21
+
22
+ def arguments
23
+ self.class.arguments.inject({}) do |hash, (type, name)|
24
+ hash.update name => instance_variable_get("@#{name}")
25
+ end
26
+ end
27
+
28
+ def to_binary
29
+ buf = Transport09::Buffer.new
30
+ buf.write :short, self.class.parent.id
31
+ buf.write :short, self.class.id
32
+
33
+ bits = []
34
+
35
+ self.class.arguments.each do |type, name|
36
+ val = instance_variable_get("@#{name}")
37
+ if type == :bit
38
+ bits << (val || false)
39
+ else
40
+ unless bits.empty?
41
+ buf.write :bit, bits
42
+ bits = []
43
+ end
44
+ buf.write type, val
45
+ end
46
+ end
47
+
48
+ buf.write :bit, bits unless bits.empty?
49
+ buf.rewind
50
+
51
+ buf
52
+ end
53
+
54
+ def to_s
55
+ to_binary.to_s
56
+ end
57
+
58
+ def to_frame channel = 0
59
+ Transport09::Method.new(self, channel)
60
+ end
61
+ end
62
+
63
+ class Header
64
+ def initialize *args
65
+ opts = args.pop if args.last.is_a? Hash
66
+ opts ||= {}
67
+
68
+ first = args.shift
69
+
70
+ if first.is_a? ::Class and first.ancestors.include? Protocol09::Class
71
+ @klass = first
72
+ @size = args.shift || 0
73
+ @weight = args.shift || 0
74
+ @properties = opts
75
+
76
+ elsif first.is_a? Transport09::Buffer or first.is_a? String
77
+ buf = first
78
+ buf = Transport09::Buffer.new(buf) unless buf.is_a? Transport09::Buffer
79
+
80
+ @klass = Protocol09.classes[buf.read(:short)]
81
+ @weight = buf.read(:short)
82
+ @size = buf.read(:longlong)
83
+
84
+ props = buf.read(:properties, *klass.properties.map{|type,_| type })
85
+ @properties = Hash[*klass.properties.map{|_,name| name }.zip(props).reject{|k,v| v.nil? }.flatten]
86
+
87
+ else
88
+ raise ArgumentError, 'Invalid argument'
89
+ end
90
+
91
+ end
92
+ attr_accessor :klass, :size, :weight, :properties
93
+
94
+ def to_binary
95
+ buf = Transport09::Buffer.new
96
+ buf.write :short, klass.id
97
+ buf.write :short, weight # XXX rabbitmq only supports weight == 0
98
+ buf.write :longlong, size
99
+ buf.write :properties, (klass.properties.map do |type, name|
100
+ [ type, properties[name] || properties[name.to_s] ]
101
+ end)
102
+ buf.rewind
103
+ buf
104
+ end
105
+
106
+ def to_s
107
+ to_binary.to_s
108
+ end
109
+
110
+ def to_frame channel = 0
111
+ Transport09::Header.new(self, channel)
112
+ end
113
+
114
+ def == header
115
+ [ :klass, :size, :weight, :properties ].inject(true) do |eql, field|
116
+ eql and __send__(field) == header.__send__(field)
117
+ end
118
+ end
119
+
120
+ def method_missing meth, *args, &blk
121
+ @properties.has_key?(meth) || @klass.properties.find{|_,name| name == meth } ? @properties[meth] :
122
+ super
123
+ end
124
+ end
125
+
126
+ def self.parse buf
127
+ buf = Transport09::Buffer.new(buf) unless buf.is_a? Transport09::Buffer
128
+ class_id, method_id = buf.read(:short, :short)
129
+ classes[class_id].methods[method_id].new(buf)
130
+ end
131
+
132
+ end
133
+ end
@@ -6,7 +6,7 @@
6
6
  # DO NOT EDIT! (edit ext/qparser.rb and config.yml instead, and run 'ruby qparser.rb')
7
7
 
8
8
  module Qrack
9
- module Protocol
9
+ module Protocol09
10
10
  HEADER = "AMQP".freeze
11
11
  VERSION_MAJOR = 0
12
12
  VERSION_MINOR = 9
@@ -75,7 +75,7 @@ module Qrack
75
75
 
76
76
  def arguments() @arguments ||= [] end
77
77
 
78
- def parent() Protocol.const_get(self.to_s[/Protocol::(.+?)::/,1]) end
78
+ def parent() Protocol09.const_get(self.to_s[/Protocol09::(.+?)::/,1]) end
79
79
  def id() self::ID end
80
80
  def name() self::NAME end
81
81
  end
@@ -113,8 +113,8 @@ module Qrack
113
113
  def self.inherited klass
114
114
  klass.const_set(:ID, #{id})
115
115
  klass.const_set(:NAME, :#{name.to_s})
116
- Protocol.classes[#{id}] = klass
117
- Protocol.classes[klass::NAME] = klass
116
+ Protocol09.classes[#{id}] = klass
117
+ Protocol09.classes[klass::NAME] = klass
118
118
  end
119
119
  ]
120
120
  end
@@ -123,7 +123,7 @@ module Qrack
123
123
  end
124
124
 
125
125
  module Qrack
126
- module Protocol
126
+ module Protocol09
127
127
  class Connection < Class( 10, :connection ); end
128
128
  class Channel < Class( 20, :channel ); end
129
129
  class Exchange < Class( 40, :exchange ); end