bunny 0.5.3 → 0.6.0
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.
- data/{README → README.rdoc} +9 -2
- data/bunny.gemspec +12 -7
- data/examples/simple_08.rb +1 -1
- data/examples/simple_09.rb +1 -1
- data/examples/simple_ack_08.rb +1 -1
- data/examples/simple_ack_09.rb +1 -1
- data/examples/simple_consumer_08.rb +6 -14
- data/examples/simple_consumer_09.rb +6 -14
- data/examples/simple_fanout_08.rb +2 -2
- data/examples/simple_fanout_09.rb +2 -2
- data/examples/simple_headers_08.rb +1 -1
- data/examples/simple_headers_09.rb +1 -1
- data/examples/simple_topic_08.rb +4 -4
- data/examples/simple_topic_09.rb +4 -4
- data/lib/bunny.rb +23 -15
- data/lib/bunny/channel08.rb +8 -2
- data/lib/bunny/channel09.rb +8 -2
- data/lib/bunny/client08.rb +67 -24
- data/lib/bunny/client09.rb +88 -48
- data/lib/bunny/exchange08.rb +55 -43
- data/lib/bunny/exchange09.rb +67 -54
- data/lib/bunny/queue08.rb +79 -137
- data/lib/bunny/queue09.rb +79 -141
- data/lib/bunny/subscription08.rb +85 -0
- data/lib/bunny/subscription09.rb +85 -0
- data/lib/qrack/client.rb +29 -10
- data/lib/qrack/protocol/spec08.rb +1 -0
- data/lib/qrack/protocol/spec09.rb +1 -0
- data/lib/qrack/qrack08.rb +1 -0
- data/lib/qrack/qrack09.rb +1 -0
- data/lib/qrack/queue.rb +1 -1
- data/lib/qrack/subscription.rb +102 -0
- data/spec/spec_08/bunny_spec.rb +6 -0
- data/spec/spec_08/connection_spec.rb +12 -0
- data/spec/spec_08/exchange_spec.rb +19 -3
- data/spec/spec_08/queue_spec.rb +87 -13
- data/spec/spec_09/bunny_spec.rb +7 -1
- data/spec/spec_09/connection_spec.rb +12 -0
- data/spec/spec_09/exchange_spec.rb +19 -3
- data/spec/spec_09/queue_spec.rb +94 -21
- metadata +11 -6
data/lib/bunny/queue08.rb
CHANGED
@@ -18,6 +18,7 @@ Queues must be attached to at least one exchange in order to receive messages fr
|
|
18
18
|
@client = client
|
19
19
|
@opts = opts
|
20
20
|
@delivery_tag = nil
|
21
|
+
@subscription = nil
|
21
22
|
|
22
23
|
# Queues without a given name are named by the server and are generally
|
23
24
|
# bound to the process that created them.
|
@@ -39,7 +40,8 @@ Queues must be attached to at least one exchange in order to receive messages fr
|
|
39
40
|
)
|
40
41
|
|
41
42
|
method = client.next_method
|
42
|
-
|
43
|
+
|
44
|
+
client.check_response(method, Qrack::Protocol::Queue::DeclareOk, "Error declaring queue #{name}")
|
43
45
|
|
44
46
|
@name = method.queue
|
45
47
|
client.queues[@name] = self
|
@@ -63,8 +65,12 @@ ask to confirm a single message or a set of messages up to and including a speci
|
|
63
65
|
=end
|
64
66
|
|
65
67
|
def ack(opts={})
|
66
|
-
#
|
67
|
-
|
68
|
+
# Set delivery tag
|
69
|
+
if delivery_tag.nil? and opts[:delivery_tag].nil?
|
70
|
+
raise Bunny::AcknowledgementError, "No delivery tag received"
|
71
|
+
else
|
72
|
+
self.delivery_tag = opts[:delivery_tag] if delivery_tag.nil?
|
73
|
+
end
|
68
74
|
|
69
75
|
client.send_frame(
|
70
76
|
Qrack::Protocol::Basic::Ack.new({:delivery_tag => delivery_tag, :multiple => false}.merge(opts))
|
@@ -104,10 +110,11 @@ bound to the direct exchange '' by default. If error occurs, a _Bunny_::_Protoco
|
|
104
110
|
:routing_key => opts.delete(:key),
|
105
111
|
:nowait => false }.merge(opts))
|
106
112
|
)
|
113
|
+
|
114
|
+
method = client.next_method
|
107
115
|
|
108
|
-
|
109
|
-
"Error binding queue #{name}"
|
110
|
-
client.next_method.is_a?(Qrack::Protocol::Queue::BindOk)
|
116
|
+
client.check_response(method, Qrack::Protocol::Queue::BindOk,
|
117
|
+
"Error binding queue: #{name} to exchange: #{exchange}")
|
111
118
|
|
112
119
|
# return message
|
113
120
|
:bind_ok
|
@@ -144,10 +151,10 @@ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
|
|
144
151
|
client.send_frame(
|
145
152
|
Qrack::Protocol::Queue::Delete.new({ :queue => name, :nowait => false }.merge(opts))
|
146
153
|
)
|
154
|
+
|
155
|
+
method = client.next_method
|
147
156
|
|
148
|
-
|
149
|
-
"Error deleting queue #{name}" unless
|
150
|
-
client.next_method.is_a?(Qrack::Protocol::Queue::DeleteOk)
|
157
|
+
client.check_response(method, Qrack::Protocol::Queue::DeleteOk, "Error deleting queue #{name}")
|
151
158
|
|
152
159
|
client.queues.delete(name)
|
153
160
|
|
@@ -162,26 +169,29 @@ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
|
|
162
169
|
Gets a message from a queue in a synchronous way. If error occurs, raises _Bunny_::_ProtocolError_.
|
163
170
|
|
164
171
|
==== OPTIONS:
|
165
|
-
|
166
|
-
* <tt>:
|
167
|
-
|
168
|
-
* <tt>:no_ack => true (_default_) or false</tt> - If set to _true_, the server does not expect an
|
169
|
-
acknowledgement message from the client. If set to _false_, the server expects an acknowledgement
|
172
|
+
|
173
|
+
* <tt>:ack => false (_default_) or true</tt> - If set to _false_, the server does not expect an
|
174
|
+
acknowledgement message from the client. If set to _true_, the server expects an acknowledgement
|
170
175
|
message from the client and will re-queue the message if it does not receive one within a time specified
|
171
176
|
by the server.
|
172
177
|
|
173
178
|
==== RETURNS:
|
174
179
|
|
175
|
-
|
176
|
-
a hash <tt>{:delivery_tag, :redelivered, :exchange, :routing_key
|
177
|
-
|
180
|
+
Hash <tt>{:header, :payload, :delivery_details}</tt>. <tt>:delivery_details</tt> is
|
181
|
+
a hash <tt>{:consumer_tag, :delivery_tag, :redelivered, :exchange, :routing_key}</tt>.
|
182
|
+
|
183
|
+
If the queue is empty the returned hash will contain the values -
|
184
|
+
|
185
|
+
:header => nil
|
186
|
+
:payload => :queue_empty
|
187
|
+
:delivery_details => nil
|
188
|
+
|
189
|
+
N.B. If a block is provided then the hash will be passed into the block and the return value
|
190
|
+
will be nil.
|
178
191
|
|
179
192
|
=end
|
180
193
|
|
181
|
-
def pop(opts = {})
|
182
|
-
|
183
|
-
# do we want the message header?
|
184
|
-
hdr = opts.delete(:header)
|
194
|
+
def pop(opts = {}, &blk)
|
185
195
|
|
186
196
|
# do we want to have to provide an acknowledgement?
|
187
197
|
ack = opts.delete(:ack)
|
@@ -196,25 +206,32 @@ a hash <tt>{:delivery_tag, :redelivered, :exchange, :routing_key, :message_count
|
|
196
206
|
method = client.next_method
|
197
207
|
|
198
208
|
if method.is_a?(Qrack::Protocol::Basic::GetEmpty) then
|
199
|
-
|
209
|
+
queue_empty = true
|
200
210
|
elsif !method.is_a?(Qrack::Protocol::Basic::GetOk)
|
201
211
|
raise Bunny::ProtocolError, "Error getting message from queue #{name}"
|
202
212
|
end
|
203
213
|
|
204
|
-
|
205
|
-
|
214
|
+
if !queue_empty
|
215
|
+
# get delivery tag to use for acknowledge
|
216
|
+
self.delivery_tag = method.delivery_tag if ack
|
206
217
|
|
207
|
-
|
218
|
+
header = client.next_payload
|
208
219
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
220
|
+
# If maximum frame size is smaller than message payload body then message
|
221
|
+
# will have a message header and several message bodies
|
222
|
+
msg = ''
|
223
|
+
while msg.length < header.size
|
224
|
+
msg += client.next_payload
|
225
|
+
end
|
226
|
+
|
227
|
+
msg_hash = {:header => header, :payload => msg, :delivery_details => method.arguments}
|
228
|
+
|
229
|
+
else
|
230
|
+
msg_hash = {:header => nil, :payload => :queue_empty, :delivery_details => nil}
|
214
231
|
end
|
215
|
-
|
216
|
-
#
|
217
|
-
|
232
|
+
|
233
|
+
# Pass message hash to block or return message hash
|
234
|
+
blk ? blk.call(msg_hash) : msg_hash
|
218
235
|
|
219
236
|
end
|
220
237
|
|
@@ -242,8 +259,10 @@ without any formal "undo" mechanism. If an error occurs raises _Bunny_::_Protoco
|
|
242
259
|
client.send_frame(
|
243
260
|
Qrack::Protocol::Queue::Purge.new({ :queue => name, :nowait => false }.merge(opts))
|
244
261
|
)
|
262
|
+
|
263
|
+
method = client.next_method
|
245
264
|
|
246
|
-
|
265
|
+
client.check_response(method, Qrack::Protocol::Queue::PurgeOk, "Error purging queue #{name}")
|
247
266
|
|
248
267
|
# return confirmation
|
249
268
|
:purge_ok
|
@@ -266,99 +285,14 @@ Returns hash {:message_count, :consumer_count}.
|
|
266
285
|
{:message_count => method.message_count, :consumer_count => method.consumer_count}
|
267
286
|
end
|
268
287
|
|
269
|
-
=begin rdoc
|
270
|
-
|
271
|
-
=== DESCRIPTION:
|
272
|
-
|
273
|
-
Asks the server to start a "consumer", which is a transient request for messages from a specific
|
274
|
-
queue. Consumers last as long as the channel they were created on, or until the client cancels them
|
275
|
-
with an _unsubscribe_. Every time a message reaches the queue it is passed to the _blk_ for
|
276
|
-
processing. If error occurs, _Bunny_::_ProtocolError_ is raised.
|
277
|
-
|
278
|
-
==== OPTIONS:
|
279
|
-
* <tt>:header => true or false (_default_)</tt> - If set to _true_, hash is delivered for each message
|
280
|
-
<tt>{:header, :delivery_details, :payload}</tt>.
|
281
|
-
* <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer. The consumer tag is
|
282
|
-
local to a connection, so two clients can use the same consumer tags. If this field is empty the
|
283
|
-
queue name is used.
|
284
|
-
* <tt>:no_ack=> true (_default_) or false</tt> - If set to _true_, the server does not expect an
|
285
|
-
acknowledgement message from the client. If set to _false_, the server expects an acknowledgement
|
286
|
-
message from the client and will re-queue the message if it does not receive one within a time specified
|
287
|
-
by the server.
|
288
|
-
* <tt>:exclusive => true or false (_default_)</tt> - Request exclusive consumer access, meaning
|
289
|
-
only this consumer can access the queue.
|
290
|
-
* <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
|
291
|
-
* <tt>:timeout => number of seconds - The subscribe loop will continue to wait for
|
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.
|
295
|
-
|
296
|
-
==== RETURNS:
|
297
|
-
|
298
|
-
If <tt>:header => true</tt> returns hash <tt>{:header, :delivery_details, :payload}</tt> for each message.
|
299
|
-
<tt>:delivery_details</tt> is a hash <tt>{:consumer_tag, :delivery_tag, :redelivered, :exchange, :routing_key}</tt>.
|
300
|
-
If <tt>:header => false</tt> only message payload is returned.
|
301
|
-
If <tt>:timeout => > 0</tt> is reached Qrack::ClientTimeout is raised
|
302
|
-
|
303
|
-
=end
|
304
288
|
|
305
|
-
|
306
|
-
#
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
# If a consumer tag is not passed in the server will generate one
|
311
|
-
consumer_tag = opts[:consumer_tag] || nil
|
312
|
-
|
313
|
-
# ignore the :nowait option if passed, otherwise program will hang waiting for a
|
314
|
-
# response from the server causing an error.
|
315
|
-
opts.delete(:nowait)
|
316
|
-
|
317
|
-
# do we want the message header?
|
318
|
-
hdr = opts.delete(:header)
|
319
|
-
|
320
|
-
# do we want to have to provide an acknowledgement?
|
321
|
-
ack = opts.delete(:ack)
|
322
|
-
|
323
|
-
client.send_frame(
|
324
|
-
Qrack::Protocol::Basic::Consume.new({ :queue => name,
|
325
|
-
:consumer_tag => consumer_tag,
|
326
|
-
:no_ack => !ack,
|
327
|
-
:nowait => false }.merge(opts))
|
328
|
-
)
|
329
|
-
|
330
|
-
raise Bunny::ProtocolError,
|
331
|
-
"Error subscribing to queue #{name}" unless
|
332
|
-
client.next_method.is_a?(Qrack::Protocol::Basic::ConsumeOk)
|
333
|
-
|
334
|
-
# Initialize message counter
|
335
|
-
counter = 0
|
336
|
-
|
337
|
-
loop do
|
338
|
-
method = client.next_method(:timeout => opts[:timeout])
|
339
|
-
|
340
|
-
# get delivery tag to use for acknowledge
|
341
|
-
self.delivery_tag = method.delivery_tag if ack
|
342
|
-
|
343
|
-
header = client.next_payload
|
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
|
351
|
-
|
352
|
-
# pass the message and related info, if requested, to the block for processing
|
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
|
360
|
-
end
|
289
|
+
def subscribe(opts = {}, &blk)
|
290
|
+
# Create subscription
|
291
|
+
s = Bunny::Subscription.new(client, self, opts)
|
292
|
+
s.start(&blk)
|
361
293
|
|
294
|
+
# Reset when subscription finished
|
295
|
+
@subscription = nil
|
362
296
|
end
|
363
297
|
|
364
298
|
=begin rdoc
|
@@ -380,20 +314,28 @@ the server will not send any more messages for that consumer.
|
|
380
314
|
=end
|
381
315
|
|
382
316
|
def unsubscribe(opts = {})
|
383
|
-
|
317
|
+
# Default consumer_tag from subscription if not passed in
|
318
|
+
consumer_tag = subscription ? subscription.consumer_tag : opts[:consumer_tag]
|
384
319
|
|
385
|
-
#
|
386
|
-
|
387
|
-
|
320
|
+
# Must have consumer tag to tell server what to unsubscribe
|
321
|
+
raise Bunny::UnsubscribeError,
|
322
|
+
"No consumer tag received" if !consumer_tag
|
388
323
|
|
389
|
-
|
324
|
+
# Cancel consumer
|
325
|
+
client.send_frame( Qrack::Protocol::Basic::Cancel.new(:consumer_tag => consumer_tag,
|
326
|
+
:nowait => false))
|
327
|
+
|
328
|
+
method = client.next_method
|
329
|
+
|
330
|
+
client.check_response(method, Qrack::Protocol::Basic::CancelOk,
|
331
|
+
"Error unsubscribing from queue #{name}")
|
390
332
|
|
391
|
-
|
392
|
-
|
393
|
-
client.next_method.is_a?(Qrack::Protocol::Basic::CancelOk)
|
333
|
+
# Reset subscription
|
334
|
+
@subscription = nil
|
394
335
|
|
395
|
-
#
|
336
|
+
# Return confirmation
|
396
337
|
:unsubscribe_ok
|
338
|
+
|
397
339
|
end
|
398
340
|
|
399
341
|
=begin rdoc
|
@@ -428,9 +370,9 @@ Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolE
|
|
428
370
|
)
|
429
371
|
)
|
430
372
|
|
431
|
-
|
432
|
-
|
433
|
-
|
373
|
+
method = client.next_method
|
374
|
+
|
375
|
+
client.check_response(method, Qrack::Protocol::Queue::UnbindOk, "Error unbinding queue #{name}")
|
434
376
|
|
435
377
|
# return message
|
436
378
|
:unbind_ok
|
data/lib/bunny/queue09.rb
CHANGED
@@ -40,7 +40,8 @@ Queues must be attached to at least one exchange in order to receive messages fr
|
|
40
40
|
)
|
41
41
|
|
42
42
|
method = client.next_method
|
43
|
-
|
43
|
+
|
44
|
+
client.check_response(method, Qrack::Protocol09::Queue::DeclareOk, "Error declaring queue #{name}")
|
44
45
|
|
45
46
|
@name = method.queue
|
46
47
|
client.queues[@name] = self
|
@@ -64,8 +65,12 @@ ask to confirm a single message or a set of messages up to and including a speci
|
|
64
65
|
=end
|
65
66
|
|
66
67
|
def ack(opts={})
|
67
|
-
#
|
68
|
-
|
68
|
+
# Set delivery tag
|
69
|
+
if delivery_tag.nil? and opts[:delivery_tag].nil?
|
70
|
+
raise Bunny::AcknowledgementError, "No delivery tag received"
|
71
|
+
else
|
72
|
+
self.delivery_tag = opts[:delivery_tag] if delivery_tag.nil?
|
73
|
+
end
|
69
74
|
|
70
75
|
client.send_frame(
|
71
76
|
Qrack::Protocol09::Basic::Ack.new({:delivery_tag => delivery_tag, :multiple => false}.merge(opts))
|
@@ -107,9 +112,10 @@ bound to the direct exchange '' by default. If error occurs, a _Bunny_::_Protoco
|
|
107
112
|
:reserved_1 => 0 }.merge(opts))
|
108
113
|
)
|
109
114
|
|
110
|
-
|
111
|
-
|
112
|
-
|
115
|
+
method = client.next_method
|
116
|
+
|
117
|
+
client.check_response(method, Qrack::Protocol09::Queue::BindOk,
|
118
|
+
"Error binding queue: #{name} to exchange: #{exchange}")
|
113
119
|
|
114
120
|
# return message
|
115
121
|
:bind_ok
|
@@ -147,9 +153,9 @@ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
|
|
147
153
|
Qrack::Protocol09::Queue::Delete.new({ :queue => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
|
148
154
|
)
|
149
155
|
|
150
|
-
|
151
|
-
|
152
|
-
|
156
|
+
method = client.next_method
|
157
|
+
|
158
|
+
client.check_response(method, Qrack::Protocol09::Queue::DeleteOk, "Error deleting queue #{name}")
|
153
159
|
|
154
160
|
client.queues.delete(name)
|
155
161
|
|
@@ -164,26 +170,29 @@ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
|
|
164
170
|
Gets a message from a queue in a synchronous way. If error occurs, raises _Bunny_::_ProtocolError_.
|
165
171
|
|
166
172
|
==== OPTIONS:
|
167
|
-
|
168
|
-
* <tt>:
|
169
|
-
|
170
|
-
* <tt>:no_ack => true (_default_) or false</tt> - If set to _true_, the server does not expect an
|
171
|
-
acknowledgement message from the client. If set to _false_, the server expects an acknowledgement
|
173
|
+
|
174
|
+
* <tt>:ack => false (_default_) or true</tt> - If set to _false_, the server does not expect an
|
175
|
+
acknowledgement message from the client. If set to _true_, the server expects an acknowledgement
|
172
176
|
message from the client and will re-queue the message if it does not receive one within a time specified
|
173
177
|
by the server.
|
174
178
|
|
175
179
|
==== RETURNS:
|
176
180
|
|
177
|
-
|
178
|
-
a hash <tt>{:delivery_tag, :redelivered, :exchange, :routing_key
|
179
|
-
|
181
|
+
Hash <tt>{:header, :payload, :delivery_details}</tt>. <tt>:delivery_details</tt> is
|
182
|
+
a hash <tt>{:consumer_tag, :delivery_tag, :redelivered, :exchange, :routing_key}</tt>.
|
183
|
+
|
184
|
+
If the queue is empty the returned hash will contain the values -
|
185
|
+
|
186
|
+
:header => nil
|
187
|
+
:payload => :queue_empty
|
188
|
+
:delivery_details => nil
|
189
|
+
|
190
|
+
N.B. If a block is provided then the hash will be passed into the block and the return value
|
191
|
+
will be nil.
|
180
192
|
|
181
193
|
=end
|
182
194
|
|
183
|
-
def pop(opts = {})
|
184
|
-
|
185
|
-
# do we want the message header?
|
186
|
-
hdr = opts.delete(:header)
|
195
|
+
def pop(opts = {}, &blk)
|
187
196
|
|
188
197
|
# do we want to have to provide an acknowledgement?
|
189
198
|
ack = opts.delete(:ack)
|
@@ -199,26 +208,33 @@ a hash <tt>{:delivery_tag, :redelivered, :exchange, :routing_key, :message_count
|
|
199
208
|
method = client.next_method
|
200
209
|
|
201
210
|
if method.is_a?(Qrack::Protocol09::Basic::GetEmpty) then
|
202
|
-
|
211
|
+
queue_empty = true
|
203
212
|
elsif !method.is_a?(Qrack::Protocol09::Basic::GetOk)
|
204
213
|
raise Bunny::ProtocolError, "Error getting message from queue #{name}"
|
205
214
|
end
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
msg
|
215
|
+
|
216
|
+
if !queue_empty
|
217
|
+
# get delivery tag to use for acknowledge
|
218
|
+
self.delivery_tag = method.delivery_tag if ack
|
219
|
+
|
220
|
+
header = client.next_payload
|
221
|
+
|
222
|
+
# If maximum frame size is smaller than message payload body then message
|
223
|
+
# will have a message header and several message bodies
|
224
|
+
msg = ''
|
225
|
+
while msg.length < header.size
|
226
|
+
msg += client.next_payload
|
227
|
+
end
|
228
|
+
|
229
|
+
msg_hash = {:header => header, :payload => msg, :delivery_details => method.arguments}
|
230
|
+
|
231
|
+
else
|
232
|
+
msg_hash = {:header => nil, :payload => :queue_empty, :delivery_details => nil}
|
217
233
|
end
|
218
234
|
|
219
|
-
#
|
220
|
-
|
221
|
-
|
235
|
+
# Pass message hash to block or return message hash
|
236
|
+
blk ? blk.call(msg_hash) : msg_hash
|
237
|
+
|
222
238
|
end
|
223
239
|
|
224
240
|
=begin rdoc
|
@@ -246,7 +262,9 @@ without any formal "undo" mechanism. If an error occurs raises _Bunny_::_Protoco
|
|
246
262
|
Qrack::Protocol09::Queue::Purge.new({ :queue => name, :nowait => false, :reserved_1 => 0 }.merge(opts))
|
247
263
|
)
|
248
264
|
|
249
|
-
|
265
|
+
method = client.next_method
|
266
|
+
|
267
|
+
client.check_response(method, Qrack::Protocol09::Queue::PurgeOk, "Error purging queue #{name}")
|
250
268
|
|
251
269
|
# return confirmation
|
252
270
|
:purge_ok
|
@@ -269,100 +287,13 @@ Returns hash {:message_count, :consumer_count}.
|
|
269
287
|
{:message_count => method.message_count, :consumer_count => method.consumer_count}
|
270
288
|
end
|
271
289
|
|
272
|
-
=begin rdoc
|
273
|
-
|
274
|
-
=== DESCRIPTION:
|
275
|
-
|
276
|
-
Asks the server to start a "consumer", which is a transient request for messages from a specific
|
277
|
-
queue. Consumers last as long as the channel they were created on, or until the client cancels them
|
278
|
-
with an _unsubscribe_. Every time a message reaches the queue it is passed to the _blk_ for
|
279
|
-
processing. If error occurs, _Bunny_::_ProtocolError_ is raised.
|
280
|
-
|
281
|
-
==== OPTIONS:
|
282
|
-
* <tt>:header => true or false (_default_)</tt> - If set to _true_, hash is delivered for each message
|
283
|
-
<tt>{:header, :delivery_details, :payload}</tt>.
|
284
|
-
* <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer. The consumer tag is
|
285
|
-
local to a connection, so two clients can use the same consumer tags. If this field is empty the
|
286
|
-
queue name is used.
|
287
|
-
* <tt>:no_ack=> true (_default_) or false</tt> - If set to _true_, the server does not expect an
|
288
|
-
acknowledgement message from the client. If set to _false_, the server expects an acknowledgement
|
289
|
-
message from the client and will re-queue the message if it does not receive one within a time specified
|
290
|
-
by the server.
|
291
|
-
* <tt>:exclusive => true or false (_default_)</tt> - Request exclusive consumer access, meaning
|
292
|
-
only this consumer can access the queue.
|
293
|
-
* <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
|
294
|
-
* <tt>:timeout => number of seconds - The subscribe loop will continue to wait for
|
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.
|
298
|
-
|
299
|
-
==== RETURNS:
|
300
|
-
|
301
|
-
If <tt>:header => true</tt> returns hash <tt>{:header, :delivery_details, :payload}</tt> for each message.
|
302
|
-
<tt>:delivery_details</tt> is a hash <tt>{:consumer_tag, :delivery_tag, :redelivered, :exchange, :routing_key}</tt>.
|
303
|
-
If <tt>:header => false</tt> only message payload is returned.
|
304
|
-
If <tt>:timeout => > 0</tt> is reached Qrack::ClientTimeout is raised
|
305
|
-
|
306
|
-
=end
|
307
|
-
|
308
290
|
def subscribe(opts = {}, &blk)
|
309
|
-
#
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
# If a consumer tag is not passed in the server will generate one
|
314
|
-
consumer_tag = opts[:consumer_tag] || nil
|
315
|
-
|
316
|
-
# ignore the :nowait option if passed, otherwise program will hang waiting for a
|
317
|
-
# response from the server causing an error.
|
318
|
-
opts.delete(:nowait)
|
319
|
-
|
320
|
-
# do we want the message header?
|
321
|
-
hdr = opts.delete(:header)
|
322
|
-
|
323
|
-
# do we want to have to provide an acknowledgement?
|
324
|
-
ack = opts.delete(:ack)
|
325
|
-
|
326
|
-
client.send_frame(
|
327
|
-
Qrack::Protocol09::Basic::Consume.new({ :reserved_1 => 0,
|
328
|
-
:queue => name,
|
329
|
-
:consumer_tag => consumer_tag,
|
330
|
-
:no_ack => !ack,
|
331
|
-
:nowait => false }.merge(opts))
|
332
|
-
)
|
333
|
-
|
334
|
-
raise Bunny::ProtocolError,
|
335
|
-
"Error subscribing to queue #{name}" unless
|
336
|
-
client.next_method.is_a?(Qrack::Protocol09::Basic::ConsumeOk)
|
337
|
-
|
338
|
-
# Initialize message counter
|
339
|
-
counter = 0
|
340
|
-
|
341
|
-
loop do
|
342
|
-
method = client.next_method(:timeout => opts[:timeout])
|
343
|
-
|
344
|
-
# get delivery tag to use for acknowledge
|
345
|
-
self.delivery_tag = method.delivery_tag if ack
|
346
|
-
|
347
|
-
header = client.next_payload
|
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
|
355
|
-
|
356
|
-
# pass the message and related info, if requested, to the block for processing
|
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
|
364
|
-
end
|
291
|
+
# Create subscription
|
292
|
+
s = Bunny::Subscription09.new(client, self, opts)
|
293
|
+
s.start(&blk)
|
365
294
|
|
295
|
+
# Reset when subscription finished
|
296
|
+
@subscription = nil
|
366
297
|
end
|
367
298
|
|
368
299
|
=begin rdoc
|
@@ -398,9 +329,9 @@ Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolE
|
|
398
329
|
)
|
399
330
|
)
|
400
331
|
|
401
|
-
|
402
|
-
|
403
|
-
|
332
|
+
method = client.next_method
|
333
|
+
|
334
|
+
client.check_response(method, Qrack::Protocol09::Queue::UnbindOk, "Error unbinding queue #{name}")
|
404
335
|
|
405
336
|
# return message
|
406
337
|
:unbind_ok
|
@@ -425,19 +356,26 @@ the server will not send any more messages for that consumer.
|
|
425
356
|
=end
|
426
357
|
|
427
358
|
def unsubscribe(opts = {})
|
428
|
-
|
359
|
+
# Default consumer_tag from subscription if not passed in
|
360
|
+
consumer_tag = subscription ? subscription.consumer_tag : opts[:consumer_tag]
|
429
361
|
|
430
|
-
#
|
431
|
-
|
432
|
-
|
362
|
+
# Must have consumer tag to tell server what to unsubscribe
|
363
|
+
raise Bunny::UnsubscribeError,
|
364
|
+
"No consumer tag received" if !consumer_tag
|
433
365
|
|
434
|
-
|
366
|
+
# Cancel consumer
|
367
|
+
client.send_frame( Qrack::Protocol09::Basic::Cancel.new(:consumer_tag => consumer_tag,
|
368
|
+
:nowait => false))
|
435
369
|
|
436
|
-
|
437
|
-
|
438
|
-
|
370
|
+
method = client.next_method
|
371
|
+
|
372
|
+
client.check_response(method, Qrack::Protocol09::Basic::CancelOk,
|
373
|
+
"Error unsubscribing from queue #{name}")
|
374
|
+
|
375
|
+
# Reset subscription
|
376
|
+
@subscription = nil
|
439
377
|
|
440
|
-
#
|
378
|
+
# Return confirmation
|
441
379
|
:unsubscribe_ok
|
442
380
|
|
443
381
|
end
|