bunny 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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