bunny 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/bunny.gemspec +4 -2
- data/examples/simple_consumer_08.rb +6 -6
- data/examples/simple_consumer_09.rb +6 -6
- data/lib/bunny.rb +1 -1
- data/lib/bunny/channel08.rb +3 -8
- data/lib/bunny/channel09.rb +3 -8
- data/lib/bunny/client08.rb +217 -344
- data/lib/bunny/client09.rb +175 -301
- data/lib/bunny/exchange08.rb +6 -1
- data/lib/bunny/exchange09.rb +6 -1
- data/lib/bunny/queue08.rb +144 -170
- data/lib/bunny/queue09.rb +160 -185
- data/lib/qrack/channel.rb +18 -0
- data/lib/qrack/client.rb +175 -2
- data/lib/qrack/qrack08.rb +2 -0
- data/lib/qrack/qrack09.rb +2 -0
- data/lib/qrack/queue.rb +53 -0
- data/spec/spec_08/exchange_spec.rb +8 -1
- data/spec/spec_08/queue_spec.rb +26 -0
- data/spec/spec_09/exchange_spec.rb +8 -1
- data/spec/spec_09/queue_spec.rb +26 -0
- metadata +4 -2
data/lib/bunny/queue09.rb
CHANGED
@@ -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
|
-
|
132
|
-
|
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
|
-
|
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
|
-
|
231
|
+
==== Options:
|
156
232
|
|
157
|
-
|
233
|
+
* <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
|
158
234
|
|
159
|
-
Returns
|
235
|
+
==== Returns:
|
160
236
|
|
237
|
+
<tt>:purge_ok</tt> if successful
|
161
238
|
=end
|
162
239
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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
|
-
|
245
|
+
client.send_frame(
|
246
|
+
Qrack::Protocol09::Queue::Purge.new({ :queue => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
|
247
|
+
)
|
169
248
|
|
170
|
-
|
249
|
+
raise Bunny::ProtocolError, "Error purging queue #{name}" unless client.next_method.is_a?(Qrack::Protocol09::Queue::PurgeOk)
|
171
250
|
|
172
|
-
|
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
|
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
|
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
|
-
|
233
|
-
|
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
|
-
|
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 =
|
345
|
+
self.delivery_tag = method.delivery_tag if ack
|
270
346
|
|
271
347
|
header = client.next_payload
|
272
|
-
|
273
|
-
|
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
|
-
|
399
|
-
|
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
|
-
====
|
416
|
+
==== OPTIONS:
|
403
417
|
|
404
|
-
* <tt>:
|
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>:
|
415
|
-
=end
|
423
|
+
<tt>:unsubscribe_ok</tt> if successful
|
416
424
|
|
417
|
-
|
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
|
431
|
+
# response from the server causing an error
|
420
432
|
opts.delete(:nowait)
|
421
433
|
|
422
|
-
|
423
|
-
|
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
|
428
|
-
client.next_method.is_a?(Qrack::Protocol09::
|
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
|
-
:
|
434
|
-
|
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
|
-
|
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
|
-
|
453
|
+
end
|
476
454
|
|
477
|
-
def bindings
|
478
|
-
@bindings ||= {}
|
479
|
-
end
|
480
455
|
end
|
481
456
|
|
482
457
|
end
|