sparqcode_bunny 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.gitignore +10 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +9 -0
  5. data/CHANGELOG +27 -0
  6. data/Gemfile +39 -0
  7. data/LICENSE +21 -0
  8. data/README.textile +82 -0
  9. data/Rakefile +14 -0
  10. data/bunny.gemspec +43 -0
  11. data/examples/simple_08.rb +32 -0
  12. data/examples/simple_09.rb +32 -0
  13. data/examples/simple_ack_08.rb +35 -0
  14. data/examples/simple_ack_09.rb +35 -0
  15. data/examples/simple_consumer_08.rb +55 -0
  16. data/examples/simple_consumer_09.rb +55 -0
  17. data/examples/simple_fanout_08.rb +41 -0
  18. data/examples/simple_fanout_09.rb +41 -0
  19. data/examples/simple_headers_08.rb +42 -0
  20. data/examples/simple_headers_09.rb +42 -0
  21. data/examples/simple_publisher_08.rb +29 -0
  22. data/examples/simple_publisher_09.rb +29 -0
  23. data/examples/simple_topic_08.rb +61 -0
  24. data/examples/simple_topic_09.rb +61 -0
  25. data/ext/amqp-0.8.json +616 -0
  26. data/ext/amqp-0.9.1.json +388 -0
  27. data/ext/config.yml +4 -0
  28. data/ext/qparser.rb +469 -0
  29. data/lib/bunny/channel08.rb +39 -0
  30. data/lib/bunny/channel09.rb +39 -0
  31. data/lib/bunny/client08.rb +472 -0
  32. data/lib/bunny/client09.rb +374 -0
  33. data/lib/bunny/consumer.rb +35 -0
  34. data/lib/bunny/exchange08.rb +171 -0
  35. data/lib/bunny/exchange09.rb +159 -0
  36. data/lib/bunny/queue08.rb +403 -0
  37. data/lib/bunny/queue09.rb +325 -0
  38. data/lib/bunny/subscription08.rb +87 -0
  39. data/lib/bunny/subscription09.rb +87 -0
  40. data/lib/bunny/system_timer.rb +14 -0
  41. data/lib/bunny/version.rb +5 -0
  42. data/lib/bunny.rb +109 -0
  43. data/lib/qrack/amq-client-url.rb +165 -0
  44. data/lib/qrack/channel.rb +20 -0
  45. data/lib/qrack/client.rb +235 -0
  46. data/lib/qrack/errors.rb +5 -0
  47. data/lib/qrack/protocol/protocol08.rb +134 -0
  48. data/lib/qrack/protocol/protocol09.rb +135 -0
  49. data/lib/qrack/protocol/spec08.rb +828 -0
  50. data/lib/qrack/protocol/spec09.rb +524 -0
  51. data/lib/qrack/qrack08.rb +20 -0
  52. data/lib/qrack/qrack09.rb +20 -0
  53. data/lib/qrack/queue.rb +40 -0
  54. data/lib/qrack/subscription.rb +112 -0
  55. data/lib/qrack/transport/buffer08.rb +278 -0
  56. data/lib/qrack/transport/buffer09.rb +280 -0
  57. data/lib/qrack/transport/frame08.rb +117 -0
  58. data/lib/qrack/transport/frame09.rb +97 -0
  59. data/spec/spec_08/bunny_spec.rb +77 -0
  60. data/spec/spec_08/connection_spec.rb +25 -0
  61. data/spec/spec_08/exchange_spec.rb +173 -0
  62. data/spec/spec_08/queue_spec.rb +235 -0
  63. data/spec/spec_09/amqp_url_spec.rb +19 -0
  64. data/spec/spec_09/bunny_spec.rb +76 -0
  65. data/spec/spec_09/connection_spec.rb +29 -0
  66. data/spec/spec_09/exchange_spec.rb +173 -0
  67. data/spec/spec_09/queue_spec.rb +248 -0
  68. metadata +151 -0
@@ -0,0 +1,159 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+
5
+ # *Exchanges* are the routing and distribution hub of AMQP. All messages that Bunny sends
6
+ # to an AMQP broker/server @have_to pass through an exchange in order to be routed to a
7
+ # destination queue. The AMQP specification defines the types of exchange that you can create.
8
+ #
9
+ # At the time of writing there are four (4) types of exchange defined:
10
+ #
11
+ # * @:direct@
12
+ # * @:fanout@
13
+ # * @:topic@
14
+ # * @:headers@
15
+ #
16
+ # AMQP-compliant brokers/servers are required to provide default exchanges for the @direct@ and
17
+ # @fanout@ exchange types. All default exchanges are prefixed with @'amq.'@, for example:
18
+ #
19
+ # * @amq.direct@
20
+ # * @amq.fanout@
21
+ # * @amq.topic@
22
+ # * @amq.match@ or @amq.headers@
23
+ #
24
+ # If you want more information about exchanges, please consult the documentation for your
25
+ # target broker/server or visit the "AMQP website":http://www.amqp.org to find the version of the
26
+ # specification that applies to your target broker/server.
27
+ class Exchange09
28
+
29
+ attr_reader :client, :type, :name, :opts, :key
30
+
31
+ def initialize(client, name, opts = {})
32
+ # check connection to server
33
+ raise Bunny::ConnectionError, 'Not connected to server' if client.status == :not_connected
34
+
35
+ @client, @name, @opts = client, name, opts
36
+
37
+ # set up the exchange type catering for default names
38
+ if name =~ /^amq\.(.+)$/
39
+ predeclared = true
40
+ new_type = $1
41
+ # handle 'amq.match' default
42
+ new_type = 'headers' if new_type == 'match'
43
+ @type = new_type.to_sym
44
+ else
45
+ @type = opts[:type] || :direct
46
+ end
47
+
48
+ @key = opts[:key]
49
+ @client.exchanges[@name] ||= self
50
+
51
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
52
+ # response that will not be sent by the server
53
+ opts.delete(:nowait)
54
+
55
+ unless predeclared or name == ''
56
+ opts = {
57
+ :exchange => name, :type => type, :nowait => false,
58
+ :deprecated_ticket => 0, :deprecated_auto_delete => false, :deprecated_internal => false
59
+ }.merge(opts)
60
+
61
+ client.send_frame(Qrack::Protocol09::Exchange::Declare.new(opts))
62
+
63
+ method = client.next_method
64
+
65
+ client.check_response(method, Qrack::Protocol09::Exchange::DeclareOk, "Error declaring exchange #{name}: type = #{type}")
66
+ end
67
+ end
68
+
69
+ # Requests that an exchange is deleted from broker/server. Removes reference from exchanges
70
+ # if successful. If an error occurs raises {Bunny::ProtocolError}.
71
+ #
72
+ # @option opts [Boolean] :if_unused (false)
73
+ # If set to @true@, the server will only delete the exchange if it has no queue bindings. If the exchange has queue bindings the server does not delete it but raises a channel exception instead.
74
+ #
75
+ # @option opts [Boolean] :nowait (false)
76
+ # Ignored by Bunny, always @false@.
77
+ #
78
+ # @return [Symbol] @:delete_ok@ if successful.
79
+ def delete(opts = {})
80
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
81
+ # response that will not be sent by the server
82
+ opts.delete(:nowait)
83
+
84
+ opts = { :exchange => name, :nowait => false, :deprecated_ticket => 0 }.merge(opts)
85
+
86
+ client.send_frame(Qrack::Protocol09::Exchange::Delete.new(opts))
87
+
88
+ method = client.next_method
89
+
90
+ client.check_response(method, Qrack::Protocol09::Exchange::DeleteOk, "Error deleting exchange #{name}")
91
+
92
+ client.exchanges.delete(name)
93
+
94
+ # return confirmation
95
+ :delete_ok
96
+ end
97
+
98
+ # Publishes a message to a specific exchange. The message will be routed to queues as defined
99
+ # by the exchange configuration and distributed to any active consumers when the transaction,
100
+ # if any, is committed.
101
+ #
102
+ # @option opts [String] :key
103
+ # Specifies the routing key for the message. The routing key is
104
+ # used for routing messages depending on the exchange configuration.
105
+ #
106
+ # @option opts [String] :content_type
107
+ # Specifies the content type for the message.
108
+ #
109
+ # @option opts [Boolean] :mandatory (false)
110
+ # Tells the server how to react if the message cannot be routed to a queue.
111
+ # If set to @true@, the server will return an unroutable message
112
+ # with a Return method. If this flag is zero, the server silently drops the message.
113
+ #
114
+ # @option opts [Boolean] :immediate (false)
115
+ # Tells the server how to react if the message cannot be routed to a queue consumer
116
+ # immediately. If set to @true@, the server will return an undeliverable message with
117
+ # a Return method. If set to @false@, the server will queue the message, but with no
118
+ # guarantee that it will ever be consumed.
119
+ #
120
+ # @option opts [Boolean] :persistent (false)
121
+ # Tells the server whether to persist the message. If set to @true@, the message will
122
+ # be persisted to disk and not lost if the server restarts. If set to @false@, the message
123
+ # will not be persisted across server restart. Setting to @true@ incurs a performance penalty
124
+ # as there is an extra cost associated with disk access.
125
+ #
126
+ # @return [NilClass] nil
127
+ def publish(data, opts = {})
128
+ opts = opts.dup
129
+ out = []
130
+
131
+ # Set up options
132
+ routing_key = opts.delete(:key) || key
133
+ mandatory = opts.delete(:mandatory)
134
+ immediate = opts.delete(:immediate)
135
+ delivery_mode = opts.delete(:persistent) ? 2 : 1
136
+ content_type = opts.delete(:content_type) || 'application/octet-stream'
137
+
138
+ out << Qrack::Protocol09::Basic::Publish.new({ :exchange => name,
139
+ :routing_key => routing_key,
140
+ :mandatory => mandatory,
141
+ :immediate => immediate,
142
+ :deprecated_ticket => 0 })
143
+ data = data.to_s
144
+ out << Qrack::Protocol09::Header.new(
145
+ Qrack::Protocol09::Basic,
146
+ data.bytesize, {
147
+ :content_type => content_type,
148
+ :delivery_mode => delivery_mode,
149
+ :priority => 0
150
+ }.merge(opts)
151
+ )
152
+ out << Qrack::Transport09::Body.new(data)
153
+
154
+ client.send_frame(*out)
155
+ end
156
+
157
+ end
158
+
159
+ end
@@ -0,0 +1,403 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+
5
+ =begin rdoc
6
+
7
+ === DESCRIPTION:
8
+
9
+ Queues store and forward messages. Queues can be configured in the server or created at runtime.
10
+ Queues must be attached to at least one exchange in order to receive messages from publishers.
11
+
12
+ =end
13
+
14
+ class Queue < Qrack::Queue
15
+
16
+ def initialize(client, name, opts = {})
17
+ # check connection to server
18
+ raise Bunny::ConnectionError, 'Not connected to server' if client.status == :not_connected
19
+
20
+ @client = client
21
+ @opts = opts
22
+ @delivery_tag = nil
23
+ @subscription = nil
24
+
25
+ # Queues without a given name are named by the server and are generally
26
+ # bound to the process that created them.
27
+ if !name
28
+ opts = {
29
+ :passive => false,
30
+ :durable => false,
31
+ :exclusive => true,
32
+ :auto_delete => true
33
+ }.merge(opts)
34
+ end
35
+
36
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
37
+ # response that will not be sent by the server
38
+ opts.delete(:nowait)
39
+
40
+ opts = { :queue => name || '', :nowait => false }.merge(opts)
41
+
42
+ client.send_frame(Qrack::Protocol::Queue::Declare.new(opts))
43
+
44
+ method = client.next_method
45
+
46
+ client.check_response(method, Qrack::Protocol::Queue::DeclareOk, "Error declaring queue #{name}")
47
+
48
+ @name = method.queue
49
+ client.queues[@name] = self
50
+ end
51
+
52
+ # @return [Bunny::Consumer] Default consumer associated with this queue (if any), or nil
53
+ # @note Default consumer is the one registered with the convenience {Bunny::Queue#subscribe} method. It has no special properties of any kind.
54
+ # @see Queue#subscribe
55
+ # @see Bunny::Consumer
56
+ # @api public
57
+ def default_consumer
58
+ @default_consumer
59
+ end
60
+
61
+
62
+ # @return [Class]
63
+ # @private
64
+ def self.consumer_class
65
+ # Bunny::Consumer
66
+ Bunny::Subscription
67
+ end # self.consumer_class
68
+
69
+ =begin rdoc
70
+
71
+ === DESCRIPTION:
72
+
73
+ Acknowledges one or more messages delivered via the _Deliver_ or _Get_-_Ok_ methods. The client can
74
+ ask to confirm a single message or a set of messages up to and including a specific message.
75
+
76
+ ==== OPTIONS:
77
+
78
+ * <tt>:delivery_tag</tt>
79
+ * <tt>:multiple => true or false (_default_)</tt> - If set to _true_, the delivery tag is treated
80
+ as "up to and including", so that the client can acknowledge multiple messages with a single
81
+ method. If set to _false_, the delivery tag refers to a single message. If the multiple field
82
+ is _true_, and the delivery tag is zero, tells the server to acknowledge all outstanding messages.
83
+
84
+ =end
85
+
86
+ def ack(opts={})
87
+ # Set delivery tag
88
+ if delivery_tag.nil? and opts[:delivery_tag].nil?
89
+ raise Bunny::AcknowledgementError, "No delivery tag received"
90
+ else
91
+ self.delivery_tag = opts[:delivery_tag] if delivery_tag.nil?
92
+ end
93
+
94
+ opts = {:delivery_tag => delivery_tag, :multiple => false}.merge(opts)
95
+
96
+ client.send_frame(Qrack::Protocol::Basic::Ack.new(opts))
97
+
98
+ # reset delivery tag
99
+ self.delivery_tag = nil
100
+ end
101
+
102
+ =begin rdoc
103
+
104
+ === DESCRIPTION:
105
+
106
+ Binds a queue to an exchange. Until a queue is bound it will not receive any messages. Queues are
107
+ bound to the direct exchange '' by default. If error occurs, a _Bunny_::_ProtocolError_ is raised.
108
+
109
+ * <tt>:key => 'routing key'* <tt>:key => 'routing_key'</tt> - Specifies the routing key for
110
+ the binding. The routing key is used for routing messages depending on the exchange configuration.
111
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
112
+
113
+ ==== RETURNS:
114
+
115
+ <tt>:bind_ok</tt> if successful.
116
+
117
+ =end
118
+
119
+ def bind(exchange, opts = {})
120
+ exchange = exchange.respond_to?(:name) ? exchange.name : exchange
121
+
122
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
123
+ # response that will not be sent by the server
124
+ opts.delete(:nowait)
125
+
126
+ opts = {
127
+ :queue => name,
128
+ :exchange => exchange,
129
+ :routing_key => opts.delete(:key),
130
+ :nowait => false
131
+ }.merge(opts)
132
+
133
+ client.send_frame(Qrack::Protocol::Queue::Bind.new(opts))
134
+
135
+ method = client.next_method
136
+
137
+ client.check_response(method, Qrack::Protocol::Queue::BindOk, "Error binding queue: #{name} to exchange: #{exchange}")
138
+
139
+ # return message
140
+ :bind_ok
141
+ end
142
+
143
+ =begin rdoc
144
+
145
+ === DESCRIPTION:
146
+
147
+ Requests that a queue is deleted from broker/server. When a queue is deleted any pending messages
148
+ are sent to a dead-letter queue if this is defined in the server configuration. Removes reference
149
+ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
150
+
151
+ ==== Options:
152
+
153
+ * <tt>:if_unused => true or false (_default_)</tt> - If set to _true_, the server will only
154
+ delete the queue if it has no consumers. If the queue has consumers the server does not
155
+ delete it but raises a channel exception instead.
156
+ * <tt>:if_empty => true or false (_default_)</tt> - If set to _true_, the server will only
157
+ delete the queue if it has no messages. If the queue is not empty the server raises a channel
158
+ exception.
159
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
160
+
161
+ ==== Returns:
162
+
163
+ <tt>:delete_ok</tt> if successful
164
+ =end
165
+
166
+ def delete(opts = {})
167
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
168
+ # response that will not be sent by the server
169
+ opts.delete(:nowait)
170
+
171
+ opts = { :queue => name, :nowait => false }.merge(opts)
172
+
173
+ client.send_frame(Qrack::Protocol::Queue::Delete.new(opts))
174
+
175
+ method = client.next_method
176
+
177
+ client.check_response(method, Qrack::Protocol::Queue::DeleteOk, "Error deleting queue #{name}")
178
+
179
+ client.queues.delete(name)
180
+
181
+ # return confirmation
182
+ :delete_ok
183
+ end
184
+
185
+ =begin rdoc
186
+
187
+ === DESCRIPTION:
188
+
189
+ Gets a message from a queue in a synchronous way. If error occurs, raises _Bunny_::_ProtocolError_.
190
+
191
+ ==== OPTIONS:
192
+
193
+ * <tt>:ack => false (_default_) or true</tt> - If set to _false_, the server does not expect an
194
+ acknowledgement message from the client. If set to _true_, the server expects an acknowledgement
195
+ message from the client and will re-queue the message if it does not receive one within a time specified
196
+ by the server.
197
+
198
+ ==== RETURNS:
199
+
200
+ Hash <tt>{:header, :payload, :delivery_details}</tt>. <tt>:delivery_details</tt> is
201
+ a hash <tt>{:consumer_tag, :delivery_tag, :redelivered, :exchange, :routing_key}</tt>.
202
+
203
+ If the queue is empty the returned hash will contain the values -
204
+
205
+ :header => nil
206
+ :payload => :queue_empty
207
+ :delivery_details => nil
208
+
209
+ N.B. If a block is provided then the hash will be passed into the block and the return value
210
+ will be nil.
211
+
212
+ =end
213
+
214
+ def pop(opts = {}, &blk)
215
+
216
+ # do we want to have to provide an acknowledgement?
217
+ ack = opts.delete(:ack)
218
+
219
+ opts = {
220
+ :queue => name,
221
+ :consumer_tag => name,
222
+ :no_ack => !ack,
223
+ :nowait => true
224
+ }.merge(opts)
225
+
226
+ client.send_frame(Qrack::Protocol::Basic::Get.new(opts))
227
+
228
+ method = client.next_method
229
+
230
+ if method.is_a?(Qrack::Protocol::Basic::GetEmpty) then
231
+ queue_empty = true
232
+ elsif !method.is_a?(Qrack::Protocol::Basic::GetOk)
233
+ raise Bunny::ProtocolError, "Error getting message from queue #{name}"
234
+ end
235
+
236
+ if !queue_empty
237
+ # get delivery tag to use for acknowledge
238
+ self.delivery_tag = method.delivery_tag if ack
239
+
240
+ header = client.next_payload
241
+
242
+ # If maximum frame size is smaller than message payload body then message
243
+ # will have a message header and several message bodies
244
+ msg = ''
245
+ while msg.length < header.size
246
+ msg << client.next_payload
247
+ end
248
+
249
+ msg_hash = {:header => header, :payload => msg, :delivery_details => method.arguments}
250
+
251
+ else
252
+ msg_hash = {:header => nil, :payload => :queue_empty, :delivery_details => nil}
253
+ end
254
+
255
+ # Pass message hash to block or return message hash
256
+ blk ? blk.call(msg_hash) : msg_hash
257
+ end
258
+
259
+ =begin rdoc
260
+
261
+ === DESCRIPTION:
262
+
263
+ Removes all messages from a queue. It does not cancel consumers. Purged messages are deleted
264
+ without any formal "undo" mechanism. If an error occurs raises _Bunny_::_ProtocolError_.
265
+
266
+ ==== Options:
267
+
268
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
269
+
270
+ ==== Returns:
271
+
272
+ <tt>:purge_ok</tt> if successful
273
+ =end
274
+
275
+ def purge(opts = {})
276
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
277
+ # response that will not be sent by the server
278
+ opts.delete(:nowait)
279
+
280
+ opts = { :queue => name, :nowait => false }.merge(opts)
281
+
282
+ client.send_frame(Qrack::Protocol::Queue::Purge.new(opts))
283
+
284
+ method = client.next_method
285
+
286
+ client.check_response(method, Qrack::Protocol::Queue::PurgeOk, "Error purging queue #{name}")
287
+
288
+ # return confirmation
289
+ :purge_ok
290
+ end
291
+
292
+ =begin rdoc
293
+
294
+ === DESCRIPTION:
295
+
296
+ Returns hash {:message_count, :consumer_count}.
297
+
298
+ =end
299
+
300
+ def status
301
+ client.send_frame(Qrack::Protocol::Queue::Declare.new(:queue => name, :passive => true))
302
+ method = client.next_method
303
+ {:message_count => method.message_count, :consumer_count => method.consumer_count}
304
+ end
305
+
306
+ def subscribe(opts = {}, &blk)
307
+ raise RuntimeError.new("This queue already has default consumer. Please instantiate Bunny::Consumer directly and call its #consume method to register additional consumers.") if @default_consumer && ! opts[:consumer_tag]
308
+
309
+ # Create a subscription.
310
+ @default_consumer = self.class.consumer_class.new(client, self, opts)
311
+ @default_consumer.consume(&blk)
312
+ end
313
+
314
+ =begin rdoc
315
+
316
+ === DESCRIPTION:
317
+
318
+ Cancels a consumer. This does not affect already delivered messages, but it does mean
319
+ the server will not send any more messages for that consumer.
320
+
321
+ ==== OPTIONS:
322
+
323
+ * <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer.
324
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
325
+
326
+ ==== Returns:
327
+
328
+ <tt>:unsubscribe_ok</tt> if successful
329
+
330
+ =end
331
+
332
+ def unsubscribe(opts = {})
333
+ # Default consumer_tag from subscription if not passed in
334
+ consumer_tag = @default_consumer ? @default_consumer.consumer_tag : opts[:consumer_tag]
335
+
336
+ # Must have consumer tag to tell server what to unsubscribe
337
+ raise Bunny::UnsubscribeError,
338
+ "No consumer tag received" if !consumer_tag
339
+
340
+ # Cancel consumer
341
+ client.send_frame(Qrack::Protocol::Basic::Cancel.new(:consumer_tag => consumer_tag,:nowait => false))
342
+
343
+ method = client.next_method
344
+
345
+ client.check_response(method, Qrack::Protocol::Basic::CancelOk, "Error unsubscribing from queue #{name}")
346
+
347
+ # Reset subscription
348
+ @default_consumer = nil
349
+
350
+ # Return confirmation
351
+ :unsubscribe_ok
352
+ end
353
+
354
+ =begin rdoc
355
+
356
+ === DESCRIPTION:
357
+
358
+ Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolError_ is raised.
359
+
360
+ ==== OPTIONS:
361
+ * <tt>:key => 'routing key'* <tt>:key => 'routing_key'</tt> - Specifies the routing key for
362
+ the binding.
363
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
364
+
365
+ ==== RETURNS:
366
+
367
+ <tt>:unbind_ok</tt> if successful.
368
+
369
+ =end
370
+
371
+ def unbind(exchange, opts = {})
372
+ exchange = exchange.respond_to?(:name) ? exchange.name : exchange
373
+
374
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
375
+ # response that will not be sent by the server
376
+ opts.delete(:nowait)
377
+
378
+ opts = {
379
+ :queue => name,
380
+ :exchange => exchange,
381
+ :routing_key => opts.delete(:key),
382
+ :nowait => false
383
+ }.merge(opts)
384
+
385
+ client.send_frame(Qrack::Protocol::Queue::Unbind.new(opts))
386
+
387
+ method = client.next_method
388
+
389
+ client.check_response(method, Qrack::Protocol::Queue::UnbindOk, "Error unbinding queue #{name}")
390
+
391
+ # return message
392
+ :unbind_ok
393
+ end
394
+
395
+ private
396
+
397
+ def exchange
398
+ @exchange ||= Bunny::Exchange.new(client, '', {:type => :direct, :key => name})
399
+ end
400
+
401
+ end
402
+
403
+ end