bunny 0.5.2 → 0.5.3

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