bunny 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.
@@ -9,9 +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 Queue09
13
- attr_reader :name, :client
14
- attr_accessor :delivery_tag
12
+ class Queue09 < Qrack::Queue
15
13
 
16
14
  def initialize(client, name, opts = {})
17
15
  # check connection to server
@@ -81,6 +79,88 @@ ask to confirm a single message or a set of messages up to and including a speci
81
79
 
82
80
  === DESCRIPTION:
83
81
 
82
+ Binds a queue to an exchange. Until a queue is bound it will not receive any messages. Queues are
83
+ bound to the direct exchange '' by default. If error occurs, a _Bunny_::_ProtocolError_ is raised.
84
+
85
+ * <tt>:key => 'routing key'* <tt>:key => 'routing_key'</tt> - Specifies the routing key for
86
+ the binding. The routing key is used for routing messages depending on the exchange configuration.
87
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
88
+
89
+ ==== RETURNS:
90
+
91
+ <tt>:bind_ok</tt> if successful.
92
+
93
+ =end
94
+
95
+ def bind(exchange, opts = {})
96
+ exchange = exchange.respond_to?(:name) ? exchange.name : exchange
97
+
98
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
99
+ # response that will not be sent by the server
100
+ opts.delete(:nowait)
101
+
102
+ client.send_frame(
103
+ Qrack::Protocol09::Queue::Bind.new({ :queue => name,
104
+ :exchange => exchange,
105
+ :routing_key => opts.delete(:key),
106
+ :nowait => false,
107
+ :reserved_1 => 0 }.merge(opts))
108
+ )
109
+
110
+ raise Bunny::ProtocolError,
111
+ "Error binding queue #{name}" unless
112
+ client.next_method.is_a?(Qrack::Protocol09::Queue::BindOk)
113
+
114
+ # return message
115
+ :bind_ok
116
+ end
117
+
118
+ =begin rdoc
119
+
120
+ === DESCRIPTION:
121
+
122
+ Requests that a queue is deleted from broker/server. When a queue is deleted any pending messages
123
+ are sent to a dead-letter queue if this is defined in the server configuration. Removes reference
124
+ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
125
+
126
+ ==== Options:
127
+
128
+ * <tt>:if_unused => true or false (_default_)</tt> - If set to _true_, the server will only
129
+ delete the queue if it has no consumers. If the queue has consumers the server does not
130
+ delete it but raises a channel exception instead.
131
+ * <tt>:if_empty => true or false (_default_)</tt> - If set to _true_, the server will only
132
+ delete the queue if it has no messages. If the queue is not empty the server raises a channel
133
+ exception.
134
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
135
+
136
+ ==== Returns:
137
+
138
+ <tt>:delete_ok</tt> if successful
139
+ =end
140
+
141
+ def delete(opts = {})
142
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
143
+ # response that will not be sent by the server
144
+ opts.delete(:nowait)
145
+
146
+ client.send_frame(
147
+ Qrack::Protocol09::Queue::Delete.new({ :queue => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
148
+ )
149
+
150
+ raise Bunny::ProtocolError,
151
+ "Error deleting queue #{name}" unless
152
+ client.next_method.is_a?(Qrack::Protocol09::Queue::DeleteOk)
153
+
154
+ client.queues.delete(name)
155
+
156
+ # return confirmation
157
+ :delete_ok
158
+ end
159
+
160
+ =begin rdoc
161
+
162
+ === DESCRIPTION:
163
+
84
164
  Gets a message from a queue in a synchronous way. If error occurs, raises _Bunny_::_ProtocolError_.
85
165
 
86
166
  ==== OPTIONS:
@@ -128,54 +208,49 @@ a hash <tt>{:delivery_tag, :redelivered, :exchange, :routing_key, :message_count
128
208
  self.delivery_tag = method.delivery_tag if ack
129
209
 
130
210
  header = client.next_payload
131
- msg = client.next_payload
132
- raise Bunny::MessageError, 'unexpected length' if msg.length < header.size
211
+
212
+ # If maximum frame size is smaller than message payload body then message
213
+ # will have a message header and several message bodies
214
+ msg = ''
215
+ while msg.length < header.size
216
+ msg += client.next_payload
217
+ end
133
218
 
134
219
  # Return message with additional info if requested
135
220
  hdr ? {:header => header, :payload => msg, :delivery_details => method.arguments} : msg
136
221
 
137
222
  end
138
-
223
+
139
224
  =begin rdoc
140
225
 
141
226
  === DESCRIPTION:
142
227
 
143
- Publishes a message to the queue via the default nameless '' direct exchange.
144
-
145
- ==== RETURNS:
146
-
147
- nil
148
-
149
- =end
150
-
151
- def publish(data, opts = {})
152
- exchange.publish(data, opts)
153
- end
228
+ Removes all messages from a queue. It does not cancel consumers. Purged messages are deleted
229
+ without any formal "undo" mechanism. If an error occurs raises _Bunny_::_ProtocolError_.
154
230
 
155
- =begin rdoc
231
+ ==== Options:
156
232
 
157
- === DESCRIPTION:
233
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
158
234
 
159
- Returns message count from Queue#status.
235
+ ==== Returns:
160
236
 
237
+ <tt>:purge_ok</tt> if successful
161
238
  =end
162
239
 
163
- def message_count
164
- s = status
165
- s[:message_count]
166
- end
240
+ def purge(opts = {})
241
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
242
+ # response that will not be sent by the server
243
+ opts.delete(:nowait)
167
244
 
168
- =begin rdoc
245
+ client.send_frame(
246
+ Qrack::Protocol09::Queue::Purge.new({ :queue => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
247
+ )
169
248
 
170
- === DESCRIPTION:
249
+ raise Bunny::ProtocolError, "Error purging queue #{name}" unless client.next_method.is_a?(Qrack::Protocol09::Queue::PurgeOk)
171
250
 
172
- Returns consumer count from Queue#status.
251
+ # return confirmation
252
+ :purge_ok
173
253
 
174
- =end
175
-
176
- def consumer_count
177
- s = status
178
- s[:consumer_count]
179
254
  end
180
255
 
181
256
  =begin rdoc
@@ -216,21 +291,27 @@ processing. If error occurs, _Bunny_::_ProtocolError_ is raised.
216
291
  * <tt>:exclusive => true or false (_default_)</tt> - Request exclusive consumer access, meaning
217
292
  only this consumer can access the queue.
218
293
  * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
219
- * <tt>:timeout => number of seconds (default = 0 no timeout) - The subscribe loop will continue to wait for
294
+ * <tt>:timeout => number of seconds - The subscribe loop will continue to wait for
220
295
  messages until terminated (Ctrl-C or kill command) or this timeout interval is reached.
296
+ * <tt>:message_max => max number messages to process</tt> - When the required number of messages
297
+ is processed subscribe loop is exited.
221
298
 
222
299
  ==== RETURNS:
223
300
 
224
301
  If <tt>:header => true</tt> returns hash <tt>{:header, :delivery_details, :payload}</tt> for each message.
225
302
  <tt>:delivery_details</tt> is a hash <tt>{:consumer_tag, :delivery_tag, :redelivered, :exchange, :routing_key}</tt>.
226
303
  If <tt>:header => false</tt> only message payload is returned.
227
- If <tt>:timeout => > 0</tt> is reached returns :timed_out
304
+ If <tt>:timeout => > 0</tt> is reached Qrack::ClientTimeout is raised
228
305
 
229
306
  =end
230
307
 
231
308
  def subscribe(opts = {}, &blk)
232
- consumer_tag = opts[:consumer_tag] || name
233
- secs = opts[:timeout] || 0
309
+ # Get maximum amount of messages to process
310
+ message_max = opts[:message_max] || nil
311
+ return if message_max == 0
312
+
313
+ # If a consumer tag is not passed in the server will generate one
314
+ consumer_tag = opts[:consumer_tag] || nil
234
315
 
235
316
  # ignore the :nowait option if passed, otherwise program will hang waiting for a
236
317
  # response from the server causing an error.
@@ -253,27 +334,33 @@ If <tt>:timeout => > 0</tt> is reached returns :timed_out
253
334
  raise Bunny::ProtocolError,
254
335
  "Error subscribing to queue #{name}" unless
255
336
  client.next_method.is_a?(Qrack::Protocol09::Basic::ConsumeOk)
337
+
338
+ # Initialize message counter
339
+ counter = 0
256
340
 
257
341
  loop do
258
- begin
259
- Timeout::timeout(secs) do
260
- @method = client.next_method
261
- end
262
- rescue Timeout::Error
263
- return :timed_out
264
- end
265
-
266
- break if @method.is_a?(Qrack::Protocol09::Basic::CancelOk)
342
+ method = client.next_method(:timeout => opts[:timeout])
267
343
 
268
344
  # get delivery tag to use for acknowledge
269
- self.delivery_tag = @method.delivery_tag if ack
345
+ self.delivery_tag = method.delivery_tag if ack
270
346
 
271
347
  header = client.next_payload
272
- msg = client.next_payload
273
- raise Bunny::MessageError, 'unexpected length' if msg.length < header.size
348
+
349
+ # If maximum frame size is smaller than message payload body then message
350
+ # will have a message header and several message bodies
351
+ msg = ''
352
+ while msg.length < header.size
353
+ msg += client.next_payload
354
+ end
274
355
 
275
356
  # pass the message and related info, if requested, to the block for processing
276
357
  blk.call(hdr ? {:header => header, :payload => msg, :delivery_details => method.arguments} : msg)
358
+
359
+ # Increment message counter
360
+ counter += 1
361
+
362
+ # Exit loop if message_max condition met
363
+ break if !message_max.nil? and counter == message_max
277
364
  end
278
365
 
279
366
  end
@@ -282,76 +369,6 @@ If <tt>:timeout => > 0</tt> is reached returns :timed_out
282
369
 
283
370
  === DESCRIPTION:
284
371
 
285
- Cancels a consumer. This does not affect already delivered messages, but it does mean
286
- the server will not send any more messages for that consumer.
287
-
288
- ==== OPTIONS:
289
-
290
- * <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer.
291
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
292
-
293
- =end
294
-
295
- def unsubscribe(opts = {})
296
- consumer_tag = opts[:consumer_tag] || name
297
-
298
- # ignore the :nowait option if passed, otherwise program will hang waiting for a
299
- # response from the server causing an error
300
- opts.delete(:nowait)
301
-
302
- client.send_frame( Qrack::Protocol09::Basic::Cancel.new({ :consumer_tag => consumer_tag }.merge(opts)))
303
-
304
- raise Bunny::ProtocolError,
305
- "Error unsubscribing from queue #{name}" unless
306
- client.next_method.is_a?(Qrack::Protocol09::Basic::CancelOk)
307
-
308
- end
309
-
310
- =begin rdoc
311
-
312
- === DESCRIPTION:
313
-
314
- Binds a queue to an exchange. Until a queue is bound it will not receive any messages. Queues are
315
- bound to the direct exchange '' by default. If error occurs, a _Bunny_::_ProtocolError_ is raised.
316
-
317
- * <tt>:key => 'routing key'* <tt>:key => 'routing_key'</tt> - Specifies the routing key for
318
- the binding. The routing key is used for routing messages depending on the exchange configuration.
319
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
320
-
321
- ==== RETURNS:
322
-
323
- <tt>:bind_ok</tt> if successful.
324
-
325
- =end
326
-
327
- def bind(exchange, opts = {})
328
- exchange = exchange.respond_to?(:name) ? exchange.name : exchange
329
-
330
- # ignore the :nowait option if passed, otherwise program will hang waiting for a
331
- # response that will not be sent by the server
332
- opts.delete(:nowait)
333
-
334
- bindings[exchange] = opts
335
- client.send_frame(
336
- Qrack::Protocol09::Queue::Bind.new({ :queue => name,
337
- :exchange => exchange,
338
- :routing_key => opts.delete(:key),
339
- :nowait => false,
340
- :reserved_1 => 0 }.merge(opts))
341
- )
342
-
343
- raise Bunny::ProtocolError,
344
- "Error binding queue #{name}" unless
345
- client.next_method.is_a?(Qrack::Protocol09::Queue::BindOk)
346
-
347
- # return message
348
- :bind_ok
349
- end
350
-
351
- =begin rdoc
352
-
353
- === DESCRIPTION:
354
-
355
372
  Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolError_ is raised.
356
373
 
357
374
  ==== OPTIONS:
@@ -367,12 +384,10 @@ Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolE
367
384
 
368
385
  def unbind(exchange, opts = {})
369
386
  exchange = exchange.respond_to?(:name) ? exchange.name : exchange
370
-
387
+
371
388
  # ignore the :nowait option if passed, otherwise program will hang waiting for a
372
389
  # response that will not be sent by the server
373
390
  opts.delete(:nowait)
374
-
375
- bindings.delete(exchange)
376
391
 
377
392
  client.send_frame(
378
393
  Qrack::Protocol09::Queue::Unbind.new({ :queue => name,
@@ -382,101 +397,61 @@ Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolE
382
397
  :reserved_1 => 0 }.merge(opts)
383
398
  )
384
399
  )
385
-
400
+
386
401
  raise Bunny::ProtocolError,
387
402
  "Error unbinding queue #{name}" unless
388
403
  client.next_method.is_a?(Qrack::Protocol09::Queue::UnbindOk)
389
-
404
+
390
405
  # return message
391
406
  :unbind_ok
392
407
  end
393
-
408
+
394
409
  =begin rdoc
395
410
 
396
411
  === DESCRIPTION:
397
412
 
398
- Requests that a queue is deleted from broker/server. When a queue is deleted any pending messages
399
- are sent to a dead-letter queue if this is defined in the server configuration. Removes reference
400
- from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
413
+ Cancels a consumer. This does not affect already delivered messages, but it does mean
414
+ the server will not send any more messages for that consumer.
401
415
 
402
- ==== Options:
416
+ ==== OPTIONS:
403
417
 
404
- * <tt>:if_unused => true or false (_default_)</tt> - If set to _true_, the server will only
405
- delete the queue if it has no consumers. If the queue has consumers the server does not
406
- delete it but raises a channel exception instead.
407
- * <tt>:if_empty => true or false (_default_)</tt> - If set to _true_, the server will only
408
- delete the queue if it has no messages. If the queue is not empty the server raises a channel
409
- exception.
418
+ * <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer.
410
419
  * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
411
420
 
412
421
  ==== Returns:
413
422
 
414
- <tt>:delete_ok</tt> if successful
415
- =end
423
+ <tt>:unsubscribe_ok</tt> if successful
416
424
 
417
- def delete(opts = {})
425
+ =end
426
+
427
+ def unsubscribe(opts = {})
428
+ consumer_tag = opts[:consumer_tag] || name
429
+
418
430
  # ignore the :nowait option if passed, otherwise program will hang waiting for a
419
- # response that will not be sent by the server
431
+ # response from the server causing an error
420
432
  opts.delete(:nowait)
421
433
 
422
- client.send_frame(
423
- Qrack::Protocol09::Queue::Delete.new({ :queue => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
424
- )
425
-
434
+ client.send_frame( Qrack::Protocol09::Basic::Cancel.new({ :consumer_tag => consumer_tag }.merge(opts)))
435
+
426
436
  raise Bunny::ProtocolError,
427
- "Error deleting queue #{name}" unless
428
- client.next_method.is_a?(Qrack::Protocol09::Queue::DeleteOk)
429
-
430
- client.queues.delete(name)
431
-
437
+ "Error unsubscribing from queue #{name}" unless
438
+ client.next_method.is_a?(Qrack::Protocol09::Basic::CancelOk)
439
+
432
440
  # return confirmation
433
- :delete_ok
434
- end
435
-
436
- =begin rdoc
437
-
438
- === DESCRIPTION:
439
-
440
- Removes all messages from a queue. It does not cancel consumers. Purged messages are deleted
441
- without any formal "undo" mechanism. If an error occurs raises _Bunny_::_ProtocolError_.
442
-
443
- ==== Options:
444
-
445
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
446
-
447
- ==== Returns:
448
-
449
- <tt>:purge_ok</tt> if successful
450
- =end
451
-
452
- def purge(opts = {})
453
- # ignore the :nowait option if passed, otherwise program will hang waiting for a
454
- # response that will not be sent by the server
455
- opts.delete(:nowait)
456
-
457
- client.send_frame(
458
- Qrack::Protocol09::Queue::Purge.new({ :queue => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
459
- )
441
+ :unsubscribe_ok
442
+
443
+ end
460
444
 
461
- raise Bunny::ProtocolError, "Error purging queue #{name}" unless client.next_method.is_a?(Qrack::Protocol09::Queue::PurgeOk)
445
+ private
462
446
 
463
- # return confirmation
464
- :purge_ok
465
-
466
- end
467
-
468
- private
469
447
  def exchange
470
448
  @exchange ||= Bunny::Exchange09.new(client, '', { :type => :direct,
471
449
  :key => name,
472
450
  :reserved_1 => 0,
473
451
  :reserved_2 => false,
474
452
  :reserved_3 => false})
475
- end
453
+ end
476
454
 
477
- def bindings
478
- @bindings ||= {}
479
- end
480
455
  end
481
456
 
482
457
  end