bunny 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,8 +12,8 @@ The Client class provides the major Bunny API methods.
12
12
  CONNECT_TIMEOUT = 1.0
13
13
  RETRY_DELAY = 10.0
14
14
 
15
- attr_reader :status, :host, :vhost, :port
16
- attr_accessor :channel, :logging, :exchanges, :queues, :ticket
15
+ attr_reader :status, :host, :vhost, :port, :logging, :spec
16
+ attr_accessor :channel, :logfile, :exchanges, :queues, :ticket
17
17
 
18
18
  =begin rdoc
19
19
 
@@ -29,24 +29,30 @@ Sets up a Bunny::Client object ready for connection to a broker/server. _Client_
29
29
  * <tt>:vhost => '_vhostname_' (default = '/')</tt>
30
30
  * <tt>:user => '_username_' (default = 'guest')</tt>
31
31
  * <tt>:pass => '_password_' (default = 'guest')</tt>
32
+ * <tt>:logfile => '_logfilepath_' (default = nil)</tt>
32
33
  * <tt>:logging => true or false (_default_)</tt> - If set to _true_, session information is sent
33
- to STDOUT.
34
+ to STDOUT if <tt>:logfile</tt> has not been specified. Otherwise, session information is written to
35
+ <tt>:logfile</tt>.
34
36
  * <tt>:insist => true or false (_default_)</tt> - In a configuration with multiple load-sharing
35
- servers, the server may respond to a Connection.Open method with a Connection.Redirect. The insist
37
+ servers, the server may respond to a Connection::Open method with a Connection::Redirect. The insist
36
38
  option, if set to _true_, tells the server that the client is insisting on a connection to the
37
39
  specified server.
38
40
 
39
41
  =end
40
42
 
41
43
  def initialize(opts = {})
44
+ @spec = opts[:spec] || '0-8'
42
45
  @host = opts[:host] || 'localhost'
43
46
  @port = opts[:port] || Qrack::Protocol::PORT
44
47
  @user = opts[:user] || 'guest'
45
48
  @pass = opts[:pass] || 'guest'
46
49
  @vhost = opts[:vhost] || '/'
50
+ @logfile = opts[:logfile] || nil
47
51
  @logging = opts[:logging] || false
48
52
  @insist = opts[:insist]
49
53
  @status = :not_connected
54
+ @logger = nil
55
+ create_logger if @logging
50
56
  end
51
57
 
52
58
  =begin rdoc
@@ -156,7 +162,7 @@ Returns hash of queues declared by Bunny.
156
162
  data = data.to_frame(channel) unless data.is_a?(Qrack::Transport::Frame)
157
163
  data.channel = channel
158
164
 
159
- log :send, data
165
+ @logger.info("send") { data } if @logging
160
166
  write(data.to_s)
161
167
  end
162
168
  nil
@@ -164,7 +170,7 @@ Returns hash of queues declared by Bunny.
164
170
 
165
171
  def next_frame
166
172
  frame = Qrack::Transport::Frame.parse(buffer)
167
- log :received, frame
173
+ @logger.info("received") { frame } if @logging
168
174
  frame
169
175
  end
170
176
 
@@ -235,7 +241,7 @@ _Bunny_::_ProtocolError_ is raised. If successful, _Client_._status_ is set to <
235
241
 
236
242
  @channel = 0
237
243
  write(Qrack::Protocol::HEADER)
238
- write([1, 1, Qrack::Protocol::VERSION_MAJOR, Qrack::Protocol::VERSION_MINOR].pack('C4'))
244
+ write([1, 1, Qrack::Protocol::VERSION_MINOR, Qrack::Protocol::VERSION_MAJOR].pack('C4'))
239
245
  raise Bunny::ProtocolError, 'Connection initiation failed' unless next_method.is_a?(Qrack::Protocol::Connection::Start)
240
246
 
241
247
  send_frame(
@@ -312,6 +318,11 @@ the message, potentially then delivering it to an alternative subscriber.
312
318
  )
313
319
 
314
320
  end
321
+
322
+ def logging=(bool)
323
+ @logging = bool
324
+ create_logger if @logging
325
+ end
315
326
 
316
327
  private
317
328
 
@@ -358,11 +369,10 @@ the message, potentially then delivering it to an alternative subscriber.
358
369
  @status = :not_connected
359
370
  end
360
371
 
361
- def log(*args)
362
- return unless logging
363
- require 'pp'
364
- pp args
365
- puts
372
+ def create_logger
373
+ @logfile ? @logger = Logger.new("#{logfile}") : @logger = Logger.new(STDOUT)
374
+ @logger.level = Logger::INFO
375
+ @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
366
376
  end
367
377
 
368
378
  end
File without changes
@@ -0,0 +1,158 @@
1
+ module Bunny
2
+
3
+ =begin rdoc
4
+
5
+ === DESCRIPTION:
6
+
7
+ *Exchanges* are the routing and distribution hub of AMQP. All messages that Bunny sends
8
+ to an AMQP broker/server _have_ to pass through an exchange in order to be routed to a
9
+ destination queue. The AMQP specification defines the types of exchange that you can create.
10
+
11
+ At the time of writing there are four (4) types of exchange defined -
12
+
13
+ * <tt>:direct</tt>
14
+ * <tt>:fanout</tt>
15
+ * <tt>:topic</tt>
16
+ * <tt>:headers</tt>
17
+
18
+ AMQP-compliant brokers/servers are required to provide default exchanges for the _direct_ and
19
+ _fanout_ exchange types. All default exchanges are prefixed with <tt>'amq.'</tt>, for example -
20
+
21
+ * <tt>amq.direct</tt>
22
+ * <tt>amq.fanout</tt>
23
+ * <tt>amq.topic</tt>
24
+ * <tt>amq.match</tt> or <tt>amq.headers</tt>
25
+
26
+ If you want more information about exchanges, please consult the documentation for your
27
+ target broker/server or visit the {AMQP website}[http://www.amqp.org] to find the version of the
28
+ specification that applies to your target broker/server.
29
+
30
+ =end
31
+
32
+ class Exchange
33
+
34
+ attr_reader :client, :type, :name, :opts, :key
35
+
36
+ def initialize(client, name, opts = {})
37
+ # check connection to server
38
+ raise Bunny::ConnectionError, 'Not connected to server' if client.status == :not_connected
39
+
40
+ @client, @name, @opts = client, name, opts
41
+
42
+ # set up the exchange type catering for default names
43
+ if name.match(/^amq\./)
44
+ new_type = name.sub(/amq\./, '')
45
+ # handle 'amq.match' default
46
+ new_type = 'headers' if new_type == 'match'
47
+ @type = new_type.to_sym
48
+ else
49
+ @type = opts[:type] || :direct
50
+ end
51
+
52
+ @key = opts[:key]
53
+ @client.exchanges[@name] ||= self
54
+
55
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
56
+ # response that will not be sent by the server
57
+ opts.delete(:nowait)
58
+
59
+ unless name == "amq.#{type}" or name == ''
60
+ client.send_frame(
61
+ Qrack::Protocol::Exchange::Declare.new(
62
+ { :exchange => name, :type => type, :nowait => false }.merge(opts)
63
+ )
64
+ )
65
+
66
+ raise Bunny::ProtocolError,
67
+ "Error declaring exchange #{name}: type = #{type}" unless
68
+ client.next_method.is_a?(Qrack::Protocol::Exchange::DeclareOk)
69
+ end
70
+ end
71
+
72
+ =begin rdoc
73
+
74
+ === DESCRIPTION:
75
+
76
+ Publishes a message to a specific exchange. The message will be routed to queues as defined
77
+ by the exchange configuration and distributed to any active consumers when the transaction,
78
+ if any, is committed.
79
+
80
+ ==== OPTIONS:
81
+
82
+ * <tt>:key => 'routing_key'</tt> - Specifies the routing key for the message. The routing key is
83
+ used for routing messages depending on the exchange configuration.
84
+ * <tt>:mandatory => true or false (_default_)</tt> - Tells the server how to react if the message
85
+ cannot be routed to a queue. If set to _true_, the server will return an unroutable message
86
+ with a Return method. If this flag is zero, the server silently drops the message.
87
+ * <tt>:immediate => true or false (_default_)</tt> - Tells the server how to react if the message
88
+ cannot be routed to a queue consumer immediately. If set to _true_, the server will return an
89
+ undeliverable message with a Return method. If set to _false_, the server will queue the message,
90
+ but with no guarantee that it will ever be consumed.
91
+
92
+ ==== RETURNS:
93
+
94
+ nil
95
+
96
+ =end
97
+
98
+ def publish(data, opts = {})
99
+ out = []
100
+
101
+ out << Qrack::Protocol::Basic::Publish.new(
102
+ { :exchange => name, :routing_key => opts.delete(:key) || key }.merge(opts)
103
+ )
104
+ data = data.to_s
105
+ out << Qrack::Protocol::Header.new(
106
+ Qrack::Protocol::Basic,
107
+ data.length, {
108
+ :content_type => 'application/octet-stream',
109
+ :delivery_mode => (opts.delete(:persistent) ? 2 : 1),
110
+ :priority => 0
111
+ }.merge(opts)
112
+ )
113
+ out << Qrack::Transport::Body.new(data)
114
+
115
+ client.send_frame(*out)
116
+ end
117
+
118
+ =begin rdoc
119
+
120
+ === DESCRIPTION:
121
+
122
+ Requests that an exchange is deleted from broker/server. Removes reference from exchanges
123
+ if successful. If an error occurs raises _Bunny_::_ProtocolError_.
124
+
125
+ ==== Options:
126
+
127
+ * <tt>:if_unused => true or false (_default_)</tt> - If set to _true_, the server will only
128
+ delete the exchange if it has no queue bindings. If the exchange has queue bindings the
129
+ server does not delete it but raises a channel exception instead.
130
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
131
+
132
+ ==== Returns:
133
+
134
+ <tt>:delete_ok</tt> if successful
135
+ =end
136
+
137
+ def delete(opts = {})
138
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
139
+ # response that will not be sent by the server
140
+ opts.delete(:nowait)
141
+
142
+ client.send_frame(
143
+ Qrack::Protocol::Exchange::Delete.new({ :exchange => name, :nowait => false }.merge(opts))
144
+ )
145
+
146
+ raise Bunny::ProtocolError,
147
+ "Error deleting exchange #{name}" unless
148
+ client.next_method.is_a?(Qrack::Protocol::Exchange::DeleteOk)
149
+
150
+ client.exchanges.delete(name)
151
+
152
+ # return confirmation
153
+ :delete_ok
154
+ end
155
+
156
+ end
157
+
158
+ end
File without changes
@@ -0,0 +1,458 @@
1
+ module Bunny
2
+
3
+ =begin rdoc
4
+
5
+ === DESCRIPTION:
6
+
7
+ Queues store and forward messages. Queues can be configured in the server or created at runtime.
8
+ Queues must be attached to at least one exchange in order to receive messages from publishers.
9
+
10
+ =end
11
+
12
+ class Queue
13
+ attr_reader :name, :client
14
+ attr_accessor :delivery_tag
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
+
24
+ # Queues without a given name are named by the server and are generally
25
+ # bound to the process that created them.
26
+ if !name
27
+ opts = {
28
+ :passive => false,
29
+ :durable => false,
30
+ :exclusive => true,
31
+ :auto_delete => true
32
+ }.merge(opts)
33
+ end
34
+
35
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
36
+ # response that will not be sent by the server
37
+ opts.delete(:nowait)
38
+
39
+ client.send_frame(
40
+ Qrack::Protocol::Queue::Declare.new({ :queue => name || '', :nowait => false }.merge(opts))
41
+ )
42
+
43
+ method = client.next_method
44
+ raise Bunny::ProtocolError, "Error declaring queue #{name}" unless method.is_a?(Qrack::Protocol::Queue::DeclareOk)
45
+
46
+ @name = method.queue
47
+ end
48
+
49
+ =begin rdoc
50
+
51
+ === DESCRIPTION:
52
+
53
+ Acknowledges one or more messages delivered via the _Deliver_ or _Get_-_Ok_ methods. The client can
54
+ ask to confirm a single message or a set of messages up to and including a specific message.
55
+
56
+ ==== OPTIONS:
57
+
58
+ * <tt>:delivery_tag</tt>
59
+ * <tt>:multiple => true or false (_default_)</tt> - If set to _true_, the delivery tag is treated
60
+ as "up to and including", so that the client can acknowledge multiple messages with a single
61
+ method. If set to _false_, the delivery tag refers to a single message. If the multiple field
62
+ is _true_, and the delivery tag is zero, tells the server to acknowledge all outstanding messages.
63
+
64
+ =end
65
+
66
+ def ack(opts={})
67
+ # If delivery tag is nil then set it to 1 to prevent errors
68
+ self.delivery_tag = 1 if self.delivery_tag.nil?
69
+
70
+ client.send_frame(
71
+ Qrack::Protocol::Basic::Ack.new({:delivery_tag => delivery_tag, :multiple => false}.merge(opts))
72
+ )
73
+
74
+ # reset delivery tag
75
+ self.delivery_tag = nil
76
+ end
77
+
78
+ =begin rdoc
79
+
80
+ === DESCRIPTION:
81
+
82
+ Gets a message from a queue in a synchronous way. If error occurs, raises _Bunny_::_ProtocolError_.
83
+
84
+ ==== OPTIONS:
85
+
86
+ * <tt>:header => true or false (_default_)</tt> - If set to _true_,
87
+ hash <tt>{:header, :delivery_details, :payload}</tt> is returned.
88
+ * <tt>:no_ack => true (_default_) or false</tt> - If set to _true_, the server does not expect an
89
+ acknowledgement message from the client. If set to _false_, the server expects an acknowledgement
90
+ message from the client and will re-queue the message if it does not receive one within a time specified
91
+ by the server.
92
+
93
+ ==== RETURNS:
94
+
95
+ If <tt>:header => true</tt> returns hash <tt>{:header, :delivery_details, :payload}</tt>. <tt>:delivery_details</tt> is
96
+ a hash <tt>{:delivery_tag, :redelivered, :exchange, :routing_key, :message_count}</tt>. If
97
+ <tt>:header => false</tt> only the message payload is returned.
98
+
99
+ =end
100
+
101
+ def pop(opts = {})
102
+
103
+ # do we want the message header?
104
+ hdr = opts.delete(:header)
105
+
106
+ # do we want to have to provide an acknowledgement?
107
+ ack = opts.delete(:ack)
108
+
109
+ client.send_frame(
110
+ Qrack::Protocol::Basic::Get.new({ :queue => name,
111
+ :consumer_tag => name,
112
+ :no_ack => !ack,
113
+ :nowait => true }.merge(opts))
114
+ )
115
+
116
+ method = client.next_method
117
+
118
+ if method.is_a?(Qrack::Protocol::Basic::GetEmpty) then
119
+ return :queue_empty
120
+ elsif !method.is_a?(Qrack::Protocol::Basic::GetOk)
121
+ raise Bunny::ProtocolError, "Error getting message from queue #{name}"
122
+ end
123
+
124
+ # get delivery tag to use for acknowledge
125
+ self.delivery_tag = method.delivery_tag if ack
126
+
127
+ header = client.next_payload
128
+ msg = client.next_payload
129
+ raise Bunny::MessageError, 'unexpected length' if msg.length < header.size
130
+
131
+ # Return message with additional info if requested
132
+ hdr ? {:header => header, :payload => msg, :delivery_details => method.arguments} : msg
133
+
134
+ end
135
+
136
+ =begin rdoc
137
+
138
+ === DESCRIPTION:
139
+
140
+ Publishes a message to the queue via the default nameless '' direct exchange.
141
+
142
+ ==== RETURNS:
143
+
144
+ nil
145
+
146
+ =end
147
+
148
+ def publish(data, opts = {})
149
+ exchange.publish(data, opts)
150
+ end
151
+
152
+ =begin rdoc
153
+
154
+ === DESCRIPTION:
155
+
156
+ Returns message count from Queue#status.
157
+
158
+ =end
159
+
160
+ def message_count
161
+ s = status
162
+ s[:message_count]
163
+ end
164
+
165
+ =begin rdoc
166
+
167
+ === DESCRIPTION:
168
+
169
+ Returns consumer count from Queue#status.
170
+
171
+ =end
172
+
173
+ def consumer_count
174
+ s = status
175
+ s[:consumer_count]
176
+ end
177
+
178
+ =begin rdoc
179
+
180
+ === DESCRIPTION:
181
+
182
+ Returns hash {:message_count, :consumer_count}.
183
+
184
+ =end
185
+
186
+ def status
187
+ client.send_frame(
188
+ Qrack::Protocol::Queue::Declare.new({ :queue => name, :passive => true })
189
+ )
190
+ method = client.next_method
191
+ {:message_count => method.message_count, :consumer_count => method.consumer_count}
192
+ end
193
+
194
+ =begin rdoc
195
+
196
+ === DESCRIPTION:
197
+
198
+ Asks the server to start a "consumer", which is a transient request for messages from a specific
199
+ queue. Consumers last as long as the channel they were created on, or until the client cancels them
200
+ with an _unsubscribe_. Every time a message reaches the queue it is passed to the _blk_ for
201
+ processing. If error occurs, _Bunny_::_ProtocolError_ is raised.
202
+
203
+ ==== OPTIONS:
204
+ * <tt>:header => true or false (_default_)</tt> - If set to _true_, hash is delivered for each message
205
+ <tt>{:header, :delivery_details, :payload}</tt>.
206
+ * <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer. The consumer tag is
207
+ local to a connection, so two clients can use the same consumer tags. If this field is empty the
208
+ queue name is used.
209
+ * <tt>:no_ack=> true (_default_) or false</tt> - If set to _true_, the server does not expect an
210
+ acknowledgement message from the client. If set to _false_, the server expects an acknowledgement
211
+ message from the client and will re-queue the message if it does not receive one within a time specified
212
+ by the server.
213
+ * <tt>:exclusive => true or false (_default_)</tt> - Request exclusive consumer access, meaning
214
+ only this consumer can access the queue.
215
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
216
+
217
+ ==== RETURNS:
218
+
219
+ If <tt>:header => true</tt> returns hash <tt>{:header, :delivery_details, :payload}</tt> for each message.
220
+ <tt>:delivery_details</tt> is a hash <tt>{:consumer_tag, :delivery_tag, :redelivered, :exchange, :routing_key}</tt>.
221
+ If <tt>:header => false</tt> only message payload is returned.
222
+
223
+ =end
224
+
225
+ def subscribe(opts = {}, &blk)
226
+ consumer_tag = opts[:consumer_tag] || name
227
+
228
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
229
+ # response from the server causing an error.
230
+ opts.delete(:nowait)
231
+
232
+ # do we want the message header?
233
+ hdr = opts.delete(:header)
234
+
235
+ # do we want to have to provide an acknowledgement?
236
+ ack = opts.delete(:ack)
237
+
238
+ 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))
243
+ )
244
+
245
+ raise Bunny::ProtocolError,
246
+ "Error subscribing to queue #{name}" unless
247
+ client.next_method.is_a?(Qrack::Protocol::Basic::ConsumeOk)
248
+
249
+ while true
250
+ method = client.next_method
251
+
252
+ break if method.is_a?(Qrack::Protocol::Basic::CancelOk)
253
+
254
+ # get delivery tag to use for acknowledge
255
+ self.delivery_tag = method.delivery_tag if ack
256
+
257
+ header = client.next_payload
258
+ msg = client.next_payload
259
+ raise Bunny::MessageError, 'unexpected length' if msg.length < header.size
260
+
261
+ # pass the message and related info, if requested, to the block for processing
262
+ blk.call(hdr ? {:header => header, :payload => msg, :delivery_details => method.arguments} : msg)
263
+ end
264
+
265
+ end
266
+
267
+ =begin rdoc
268
+
269
+ === DESCRIPTION:
270
+
271
+ Cancels a consumer. This does not affect already delivered messages, but it does mean
272
+ the server will not send any more messages for that consumer.
273
+
274
+ ==== OPTIONS:
275
+
276
+ * <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer.
277
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
278
+
279
+ =end
280
+
281
+ def unsubscribe(opts = {})
282
+ consumer_tag = opts[:consumer_tag] || name
283
+
284
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
285
+ # response from the server causing an error
286
+ opts.delete(:nowait)
287
+
288
+ client.send_frame( Qrack::Protocol::Basic::Cancel.new({ :consumer_tag => consumer_tag }.merge(opts)))
289
+
290
+ end
291
+
292
+ =begin rdoc
293
+
294
+ === DESCRIPTION:
295
+
296
+ Binds a queue to an exchange. Until a queue is bound it will not receive any messages. Queues are
297
+ bound to the direct exchange '' by default. If error occurs, a _Bunny_::_ProtocolError_ is raised.
298
+
299
+ * <tt>:key => 'routing key'* <tt>:key => 'routing_key'</tt> - Specifies the routing key for
300
+ the binding. The routing key is used for routing messages depending on the exchange configuration.
301
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
302
+
303
+ ==== RETURNS:
304
+
305
+ <tt>:bind_ok</tt> if successful.
306
+
307
+ =end
308
+
309
+ def bind(exchange, opts = {})
310
+ exchange = exchange.respond_to?(:name) ? exchange.name : exchange
311
+
312
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
313
+ # response that will not be sent by the server
314
+ opts.delete(:nowait)
315
+
316
+ bindings[exchange] = opts
317
+ client.send_frame(
318
+ Qrack::Protocol::Queue::Bind.new({ :queue => name,
319
+ :exchange => exchange,
320
+ :routing_key => opts.delete(:key),
321
+ :nowait => false }.merge(opts))
322
+ )
323
+
324
+ raise Bunny::ProtocolError,
325
+ "Error binding queue #{name}" unless
326
+ client.next_method.is_a?(Qrack::Protocol::Queue::BindOk)
327
+
328
+ # return message
329
+ :bind_ok
330
+ end
331
+
332
+ =begin rdoc
333
+
334
+ === DESCRIPTION:
335
+
336
+ Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolError_ is raised.
337
+
338
+ ==== OPTIONS:
339
+ * <tt>:key => 'routing key'* <tt>:key => 'routing_key'</tt> - Specifies the routing key for
340
+ the binding.
341
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
342
+
343
+ ==== RETURNS:
344
+
345
+ <tt>:unbind_ok</tt> if successful.
346
+
347
+ =end
348
+
349
+ def unbind(exchange, opts = {})
350
+ exchange = exchange.respond_to?(:name) ? exchange.name : exchange
351
+
352
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
353
+ # response that will not be sent by the server
354
+ opts.delete(:nowait)
355
+
356
+ bindings.delete(exchange)
357
+
358
+ client.send_frame(
359
+ Qrack::Protocol::Queue::Unbind.new({ :queue => name,
360
+ :exchange => exchange,
361
+ :routing_key => opts.delete(:key),
362
+ :nowait => false }.merge(opts)
363
+ )
364
+ )
365
+
366
+ raise Bunny::ProtocolError,
367
+ "Error unbinding queue #{name}" unless
368
+ client.next_method.is_a?(Qrack::Protocol::Queue::UnbindOk)
369
+
370
+ # return message
371
+ :unbind_ok
372
+ end
373
+
374
+ =begin rdoc
375
+
376
+ === DESCRIPTION:
377
+
378
+ Requests that a queue is deleted from broker/server. When a queue is deleted any pending messages
379
+ are sent to a dead-letter queue if this is defined in the server configuration. Removes reference
380
+ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
381
+
382
+ ==== Options:
383
+
384
+ * <tt>:if_unused => true or false (_default_)</tt> - If set to _true_, the server will only
385
+ delete the queue if it has no consumers. If the queue has consumers the server does not
386
+ delete it but raises a channel exception instead.
387
+ * <tt>:if_empty => true or false (_default_)</tt> - If set to _true_, the server will only
388
+ delete the queue if it has no messages. If the queue is not empty the server raises a channel
389
+ exception.
390
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
391
+
392
+ ==== Returns:
393
+
394
+ <tt>:delete_ok</tt> if successful
395
+ =end
396
+
397
+ def delete(opts = {})
398
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
399
+ # response that will not be sent by the server
400
+ opts.delete(:nowait)
401
+
402
+ client.send_frame(
403
+ Qrack::Protocol::Queue::Delete.new({ :queue => name, :nowait => false }.merge(opts))
404
+ )
405
+
406
+ raise Bunny::ProtocolError,
407
+ "Error deleting queue #{name}" unless
408
+ client.next_method.is_a?(Qrack::Protocol::Queue::DeleteOk)
409
+
410
+ client.queues.delete(name)
411
+
412
+ # return confirmation
413
+ :delete_ok
414
+ end
415
+
416
+ =begin rdoc
417
+
418
+ === DESCRIPTION:
419
+
420
+ Removes all messages from a queue. It does not cancel consumers. Purged messages are deleted
421
+ without any formal "undo" mechanism. If an error occurs raises _Bunny_::_ProtocolError_.
422
+
423
+ ==== Options:
424
+
425
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
426
+
427
+ ==== Returns:
428
+
429
+ <tt>:purge_ok</tt> if successful
430
+ =end
431
+
432
+ def purge(opts = {})
433
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
434
+ # response that will not be sent by the server
435
+ opts.delete(:nowait)
436
+
437
+ client.send_frame(
438
+ Qrack::Protocol::Queue::Purge.new({ :queue => name, :nowait => false }.merge(opts))
439
+ )
440
+
441
+ raise Bunny::ProtocolError, "Error purging queue #{name}" unless client.next_method.is_a?(Qrack::Protocol::Queue::PurgeOk)
442
+
443
+ # return confirmation
444
+ :purge_ok
445
+
446
+ end
447
+
448
+ private
449
+ def exchange
450
+ @exchange ||= Bunny::Exchange.new(client, '', {:type => :direct, :key => name})
451
+ end
452
+
453
+ def bindings
454
+ @bindings ||= {}
455
+ end
456
+ end
457
+
458
+ end