sparqcode_bunny 0.0.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 (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