bunny 0.6.3.rc2 → 0.7
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/.gitignore +8 -0
- data/.rspec +3 -0
- data/.travis.yml +15 -0
- data/.yardopts +9 -0
- data/CHANGELOG +3 -0
- data/Gemfile +39 -0
- data/Gemfile.lock +34 -0
- data/LICENSE +5 -4
- data/README.textile +54 -0
- data/Rakefile +15 -13
- data/bunny.gemspec +42 -61
- data/examples/simple_08.rb +4 -2
- data/examples/simple_09.rb +4 -2
- data/examples/simple_ack_08.rb +3 -1
- data/examples/simple_ack_09.rb +3 -1
- data/examples/simple_consumer_08.rb +4 -2
- data/examples/simple_consumer_09.rb +4 -2
- data/examples/simple_fanout_08.rb +3 -1
- data/examples/simple_fanout_09.rb +3 -1
- data/examples/simple_headers_08.rb +5 -3
- data/examples/simple_headers_09.rb +5 -3
- data/examples/simple_publisher_08.rb +3 -1
- data/examples/simple_publisher_09.rb +3 -1
- data/examples/simple_topic_08.rb +5 -3
- data/examples/simple_topic_09.rb +5 -3
- data/ext/amqp-0.8.json +616 -0
- data/ext/amqp-0.9.1.json +388 -0
- data/ext/config.yml +4 -0
- data/ext/qparser.rb +463 -0
- data/lib/bunny.rb +88 -66
- data/lib/bunny/channel08.rb +38 -38
- data/lib/bunny/channel09.rb +37 -37
- data/lib/bunny/client08.rb +184 -206
- data/lib/bunny/client09.rb +277 -363
- data/lib/bunny/consumer.rb +35 -0
- data/lib/bunny/exchange08.rb +37 -41
- data/lib/bunny/exchange09.rb +106 -124
- data/lib/bunny/queue08.rb +216 -202
- data/lib/bunny/queue09.rb +256 -326
- data/lib/bunny/subscription08.rb +30 -29
- data/lib/bunny/subscription09.rb +84 -83
- data/lib/bunny/version.rb +5 -0
- data/lib/qrack/amq-client-url.rb +165 -0
- data/lib/qrack/channel.rb +19 -17
- data/lib/qrack/client.rb +152 -151
- data/lib/qrack/errors.rb +5 -0
- data/lib/qrack/protocol/protocol08.rb +132 -130
- data/lib/qrack/protocol/protocol09.rb +133 -131
- data/lib/qrack/protocol/spec08.rb +2 -0
- data/lib/qrack/protocol/spec09.rb +2 -0
- data/lib/qrack/qrack08.rb +7 -10
- data/lib/qrack/qrack09.rb +7 -10
- data/lib/qrack/queue.rb +27 -40
- data/lib/qrack/subscription.rb +102 -101
- data/lib/qrack/transport/buffer08.rb +266 -264
- data/lib/qrack/transport/buffer09.rb +268 -264
- data/lib/qrack/transport/frame08.rb +13 -11
- data/lib/qrack/transport/frame09.rb +9 -7
- data/spec/spec_08/bunny_spec.rb +48 -45
- data/spec/spec_08/connection_spec.rb +10 -7
- data/spec/spec_08/exchange_spec.rb +145 -143
- data/spec/spec_08/queue_spec.rb +161 -161
- data/spec/spec_09/bunny_spec.rb +46 -44
- data/spec/spec_09/connection_spec.rb +15 -8
- data/spec/spec_09/exchange_spec.rb +147 -145
- data/spec/spec_09/queue_spec.rb +182 -184
- metadata +60 -41
- data/README.rdoc +0 -66
data/lib/bunny/queue08.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Bunny
|
2
|
-
|
4
|
+
|
3
5
|
=begin rdoc
|
4
6
|
|
5
7
|
=== DESCRIPTION:
|
@@ -9,14 +11,14 @@ Queues must be attached to at least one exchange in order to receive messages fr
|
|
9
11
|
|
10
12
|
=end
|
11
13
|
|
12
|
-
|
14
|
+
class Queue < Qrack::Queue
|
15
|
+
|
16
|
+
def initialize(client, name, opts = {})
|
17
|
+
# check connection to server
|
18
|
+
raise Bunny::ConnectionError, 'Not connected to server' if client.status == :not_connected
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
raise Bunny::ConnectionError, 'Not connected to server' if client.status == :not_connected
|
17
|
-
|
18
|
-
@client = client
|
19
|
-
@opts = opts
|
20
|
+
@client = client
|
21
|
+
@opts = opts
|
20
22
|
@delivery_tag = nil
|
21
23
|
@subscription = nil
|
22
24
|
|
@@ -30,22 +32,39 @@ Queues must be attached to at least one exchange in order to receive messages fr
|
|
30
32
|
:auto_delete => true
|
31
33
|
}.merge(opts)
|
32
34
|
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
|
36
|
+
# ignore the :nowait option if passed, otherwise program will hang waiting for a
|
37
|
+
# response that will not be sent by the server
|
38
|
+
opts.delete(:nowait)
|
39
|
+
|
40
|
+
opts = { :queue => name || '', :nowait => false }.merge(opts)
|
41
|
+
|
42
|
+
client.send_frame(Qrack::Protocol::Queue::Declare.new(opts))
|
43
|
+
|
42
44
|
method = client.next_method
|
43
45
|
|
44
|
-
|
46
|
+
client.check_response(method, Qrack::Protocol::Queue::DeclareOk, "Error declaring queue #{name}")
|
45
47
|
|
46
48
|
@name = method.queue
|
47
|
-
|
48
|
-
|
49
|
+
client.queues[@name] = self
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Bunny::Consumer] Default consumer associated with this queue (if any), or nil
|
53
|
+
# @note Default consumer is the one registered with the convenience {Bunny::Queue#subscribe} method. It has no special properties of any kind.
|
54
|
+
# @see Queue#subscribe
|
55
|
+
# @see Bunny::Consumer
|
56
|
+
# @api public
|
57
|
+
def default_consumer
|
58
|
+
@default_consumer
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# @return [Class]
|
63
|
+
# @private
|
64
|
+
def self.consumer_class
|
65
|
+
# Bunny::Consumer
|
66
|
+
Bunny::Subscription
|
67
|
+
end # self.consumer_class
|
49
68
|
|
50
69
|
=begin rdoc
|
51
70
|
|
@@ -63,21 +82,21 @@ ask to confirm a single message or a set of messages up to and including a speci
|
|
63
82
|
is _true_, and the delivery tag is zero, tells the server to acknowledge all outstanding messages.
|
64
83
|
|
65
84
|
=end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
)
|
78
|
-
|
79
|
-
|
80
|
-
|
85
|
+
|
86
|
+
def ack(opts={})
|
87
|
+
# Set delivery tag
|
88
|
+
if delivery_tag.nil? and opts[:delivery_tag].nil?
|
89
|
+
raise Bunny::AcknowledgementError, "No delivery tag received"
|
90
|
+
else
|
91
|
+
self.delivery_tag = opts[:delivery_tag] if delivery_tag.nil?
|
92
|
+
end
|
93
|
+
|
94
|
+
opts = {:delivery_tag => delivery_tag, :multiple => false}.merge(opts)
|
95
|
+
|
96
|
+
client.send_frame(Qrack::Protocol::Basic::Ack.new(opts))
|
97
|
+
|
98
|
+
# reset delivery tag
|
99
|
+
self.delivery_tag = nil
|
81
100
|
end
|
82
101
|
|
83
102
|
=begin rdoc
|
@@ -97,29 +116,30 @@ bound to the direct exchange '' by default. If error occurs, a _Bunny_::_Protoco
|
|
97
116
|
|
98
117
|
=end
|
99
118
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
119
|
+
def bind(exchange, opts = {})
|
120
|
+
exchange = exchange.respond_to?(:name) ? exchange.name : exchange
|
121
|
+
|
122
|
+
# ignore the :nowait option if passed, otherwise program will hang waiting for a
|
123
|
+
# response that will not be sent by the server
|
124
|
+
opts.delete(:nowait)
|
125
|
+
|
126
|
+
opts = {
|
127
|
+
:queue => name,
|
128
|
+
:exchange => exchange,
|
129
|
+
:routing_key => opts.delete(:key),
|
130
|
+
:nowait => false
|
131
|
+
}.merge(opts)
|
132
|
+
|
133
|
+
client.send_frame(Qrack::Protocol::Queue::Bind.new(opts))
|
134
|
+
|
135
|
+
method = client.next_method
|
136
|
+
|
137
|
+
client.check_response(method, Qrack::Protocol::Queue::BindOk, "Error binding queue: #{name} to exchange: #{exchange}")
|
138
|
+
|
139
|
+
# return message
|
140
|
+
:bind_ok
|
141
|
+
end
|
142
|
+
|
123
143
|
=begin rdoc
|
124
144
|
|
125
145
|
=== DESCRIPTION:
|
@@ -143,24 +163,24 @@ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
|
|
143
163
|
<tt>:delete_ok</tt> if successful
|
144
164
|
=end
|
145
165
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
166
|
+
def delete(opts = {})
|
167
|
+
# ignore the :nowait option if passed, otherwise program will hang waiting for a
|
168
|
+
# response that will not be sent by the server
|
169
|
+
opts.delete(:nowait)
|
170
|
+
|
171
|
+
opts = { :queue => name, :nowait => false }.merge(opts)
|
150
172
|
|
151
|
-
|
152
|
-
Qrack::Protocol::Queue::Delete.new({ :queue => name, :nowait => false }.merge(opts))
|
153
|
-
)
|
154
|
-
|
155
|
-
method = client.next_method
|
173
|
+
client.send_frame(Qrack::Protocol::Queue::Delete.new(opts))
|
156
174
|
|
157
|
-
|
175
|
+
method = client.next_method
|
158
176
|
|
159
|
-
|
177
|
+
client.check_response(method, Qrack::Protocol::Queue::DeleteOk, "Error deleting queue #{name}")
|
160
178
|
|
161
|
-
|
162
|
-
|
163
|
-
|
179
|
+
client.queues.delete(name)
|
180
|
+
|
181
|
+
# return confirmation
|
182
|
+
:delete_ok
|
183
|
+
end
|
164
184
|
|
165
185
|
=begin rdoc
|
166
186
|
|
@@ -169,7 +189,7 @@ from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
|
|
169
189
|
Gets a message from a queue in a synchronous way. If error occurs, raises _Bunny_::_ProtocolError_.
|
170
190
|
|
171
191
|
==== OPTIONS:
|
172
|
-
|
192
|
+
|
173
193
|
* <tt>:ack => false (_default_) or true</tt> - If set to _false_, the server does not expect an
|
174
194
|
acknowledgement message from the client. If set to _true_, the server expects an acknowledgement
|
175
195
|
message from the client and will re-queue the message if it does not receive one within a time specified
|
@@ -191,50 +211,51 @@ will be nil.
|
|
191
211
|
|
192
212
|
=end
|
193
213
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
214
|
+
def pop(opts = {}, &blk)
|
215
|
+
|
216
|
+
# do we want to have to provide an acknowledgement?
|
217
|
+
ack = opts.delete(:ack)
|
218
|
+
|
219
|
+
opts = {
|
220
|
+
:queue => name,
|
221
|
+
:consumer_tag => name,
|
222
|
+
:no_ack => !ack,
|
223
|
+
:nowait => true
|
224
|
+
}.merge(opts)
|
225
|
+
|
226
|
+
client.send_frame(Qrack::Protocol::Basic::Get.new(opts))
|
227
|
+
|
228
|
+
method = client.next_method
|
229
|
+
|
230
|
+
if method.is_a?(Qrack::Protocol::Basic::GetEmpty) then
|
231
|
+
queue_empty = true
|
232
|
+
elsif !method.is_a?(Qrack::Protocol::Basic::GetOk)
|
233
|
+
raise Bunny::ProtocolError, "Error getting message from queue #{name}"
|
234
|
+
end
|
235
|
+
|
236
|
+
if !queue_empty
|
237
|
+
# get delivery tag to use for acknowledge
|
238
|
+
self.delivery_tag = method.delivery_tag if ack
|
239
|
+
|
240
|
+
header = client.next_payload
|
241
|
+
|
242
|
+
# If maximum frame size is smaller than message payload body then message
|
243
|
+
# will have a message header and several message bodies
|
244
|
+
msg = ''
|
245
|
+
while msg.length < header.size
|
246
|
+
msg << client.next_payload
|
247
|
+
end
|
248
|
+
|
249
|
+
msg_hash = {:header => header, :payload => msg, :delivery_details => method.arguments}
|
250
|
+
|
251
|
+
else
|
252
|
+
msg_hash = {:header => nil, :payload => :queue_empty, :delivery_details => nil}
|
253
|
+
end
|
254
|
+
|
255
|
+
# Pass message hash to block or return message hash
|
256
|
+
blk ? blk.call(msg_hash) : msg_hash
|
257
|
+
end
|
258
|
+
|
238
259
|
=begin rdoc
|
239
260
|
|
240
261
|
=== DESCRIPTION:
|
@@ -251,23 +272,22 @@ without any formal "undo" mechanism. If an error occurs raises _Bunny_::_Protoco
|
|
251
272
|
<tt>:purge_ok</tt> if successful
|
252
273
|
=end
|
253
274
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
275
|
+
def purge(opts = {})
|
276
|
+
# ignore the :nowait option if passed, otherwise program will hang waiting for a
|
277
|
+
# response that will not be sent by the server
|
278
|
+
opts.delete(:nowait)
|
258
279
|
|
259
|
-
|
260
|
-
Qrack::Protocol::Queue::Purge.new({ :queue => name, :nowait => false }.merge(opts))
|
261
|
-
)
|
262
|
-
|
263
|
-
method = client.next_method
|
280
|
+
opts = { :queue => name, :nowait => false }.merge(opts)
|
264
281
|
|
265
|
-
|
282
|
+
client.send_frame(Qrack::Protocol::Queue::Purge.new(opts))
|
283
|
+
|
284
|
+
method = client.next_method
|
266
285
|
|
267
|
-
|
268
|
-
:purge_ok
|
286
|
+
client.check_response(method, Qrack::Protocol::Queue::PurgeOk, "Error purging queue #{name}")
|
269
287
|
|
270
|
-
|
288
|
+
# return confirmation
|
289
|
+
:purge_ok
|
290
|
+
end
|
271
291
|
|
272
292
|
=begin rdoc
|
273
293
|
|
@@ -276,25 +296,21 @@ without any formal "undo" mechanism. If an error occurs raises _Bunny_::_Protoco
|
|
276
296
|
Returns hash {:message_count, :consumer_count}.
|
277
297
|
|
278
298
|
=end
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
end
|
287
|
-
|
288
|
-
|
299
|
+
|
300
|
+
def status
|
301
|
+
client.send_frame(Qrack::Protocol::Queue::Declare.new(:queue => name, :passive => true))
|
302
|
+
method = client.next_method
|
303
|
+
{:message_count => method.message_count, :consumer_count => method.consumer_count}
|
304
|
+
end
|
305
|
+
|
289
306
|
def subscribe(opts = {}, &blk)
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
307
|
+
raise RuntimeError.new("This queue already has default consumer. Please instantiate Bunny::Consumer directly and call its #consume method to register additional consumers.") if @default_consumer && ! opts[:consumer_tag]
|
308
|
+
|
309
|
+
# Create a subscription.
|
310
|
+
@default_consumer = self.class.consumer_class.new(client, self, opts)
|
311
|
+
@default_consumer.consume(&blk)
|
312
|
+
end
|
313
|
+
|
298
314
|
=begin rdoc
|
299
315
|
|
300
316
|
=== DESCRIPTION:
|
@@ -312,30 +328,27 @@ the server will not send any more messages for that consumer.
|
|
312
328
|
<tt>:unsubscribe_ok</tt> if successful
|
313
329
|
|
314
330
|
=end
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
331
|
+
|
332
|
+
def unsubscribe(opts = {})
|
333
|
+
# Default consumer_tag from subscription if not passed in
|
334
|
+
consumer_tag = @default_consumer ? @default_consumer.consumer_tag : opts[:consumer_tag]
|
335
|
+
|
336
|
+
# Must have consumer tag to tell server what to unsubscribe
|
337
|
+
raise Bunny::UnsubscribeError,
|
338
|
+
"No consumer tag received" if !consumer_tag
|
339
|
+
|
324
340
|
# Cancel consumer
|
325
|
-
client.send_frame(
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
# Return confirmation
|
337
|
-
:unsubscribe_ok
|
338
|
-
|
341
|
+
client.send_frame(Qrack::Protocol::Basic::Cancel.new(:consumer_tag => consumer_tag,:nowait => false))
|
342
|
+
|
343
|
+
method = client.next_method
|
344
|
+
|
345
|
+
client.check_response(method, Qrack::Protocol::Basic::CancelOk, "Error unsubscribing from queue #{name}")
|
346
|
+
|
347
|
+
# Reset subscription
|
348
|
+
@default_consumer = nil
|
349
|
+
|
350
|
+
# Return confirmation
|
351
|
+
:unsubscribe_ok
|
339
352
|
end
|
340
353
|
|
341
354
|
=begin rdoc
|
@@ -355,35 +368,36 @@ Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolE
|
|
355
368
|
|
356
369
|
=end
|
357
370
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
371
|
+
def unbind(exchange, opts = {})
|
372
|
+
exchange = exchange.respond_to?(:name) ? exchange.name : exchange
|
373
|
+
|
374
|
+
# ignore the :nowait option if passed, otherwise program will hang waiting for a
|
375
|
+
# response that will not be sent by the server
|
376
|
+
opts.delete(:nowait)
|
377
|
+
|
378
|
+
opts = {
|
379
|
+
:queue => name,
|
380
|
+
:exchange => exchange,
|
381
|
+
:routing_key => opts.delete(:key),
|
382
|
+
:nowait => false
|
383
|
+
}.merge(opts)
|
384
|
+
|
385
|
+
client.send_frame(Qrack::Protocol::Queue::Unbind.new(opts))
|
386
|
+
|
387
|
+
method = client.next_method
|
388
|
+
|
389
|
+
client.check_response(method, Qrack::Protocol::Queue::UnbindOk, "Error unbinding queue #{name}")
|
390
|
+
|
391
|
+
# return message
|
392
|
+
:unbind_ok
|
393
|
+
end
|
394
|
+
|
395
|
+
private
|
396
|
+
|
397
|
+
def exchange
|
398
|
+
@exchange ||= Bunny::Exchange.new(client, '', {:type => :direct, :key => name})
|
399
|
+
end
|
400
|
+
|
401
|
+
end
|
402
|
+
|
389
403
|
end
|