amq-client 0.7.0.alpha34 → 0.7.0.alpha35

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/.travis.yml +4 -0
  2. data/Gemfile +1 -1
  3. data/README.textile +1 -1
  4. data/bin/ci/before_build.sh +24 -0
  5. data/examples/eventmachine_adapter/extensions/rabbitmq/handling_confirm_select_ok.rb +2 -2
  6. data/examples/eventmachine_adapter/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +1 -1
  7. data/examples/eventmachine_adapter/extensions/rabbitmq/publisher_confirmations_with_unroutable_message.rb +1 -1
  8. data/lib/amq/client.rb +29 -17
  9. data/lib/amq/client/adapter.rb +8 -504
  10. data/lib/amq/client/adapters/coolio.rb +4 -282
  11. data/lib/amq/client/adapters/event_machine.rb +4 -382
  12. data/lib/amq/client/async/adapter.rb +517 -0
  13. data/lib/amq/client/async/adapters/coolio.rb +291 -0
  14. data/lib/amq/client/async/adapters/event_machine.rb +392 -0
  15. data/lib/amq/client/async/adapters/eventmachine.rb +1 -0
  16. data/lib/amq/client/async/callbacks.rb +71 -0
  17. data/lib/amq/client/async/channel.rb +385 -0
  18. data/lib/amq/client/async/entity.rb +66 -0
  19. data/lib/amq/client/async/exchange.rb +157 -0
  20. data/lib/amq/client/async/extensions/rabbitmq/basic.rb +38 -0
  21. data/lib/amq/client/async/extensions/rabbitmq/confirm.rb +248 -0
  22. data/lib/amq/client/async/queue.rb +455 -0
  23. data/lib/amq/client/callbacks.rb +6 -65
  24. data/lib/amq/client/channel.rb +4 -376
  25. data/lib/amq/client/entity.rb +6 -57
  26. data/lib/amq/client/exchange.rb +4 -148
  27. data/lib/amq/client/extensions/rabbitmq/basic.rb +4 -28
  28. data/lib/amq/client/extensions/rabbitmq/confirm.rb +5 -240
  29. data/lib/amq/client/queue.rb +5 -450
  30. data/lib/amq/client/version.rb +1 -1
  31. data/spec/unit/client_spec.rb +10 -30
  32. metadata +16 -22
@@ -1,453 +1,8 @@
1
- # encoding: utf-8
2
-
3
- require "amq/client/entity"
4
- require "amq/client/adapter"
5
- require "amq/client/server_named_entity"
6
- require "amq/protocol/get_response"
1
+ require "amq/client/async/queue"
7
2
 
8
3
  module AMQ
9
4
  module Client
10
- class Queue
11
-
12
- #
13
- # Behaviors
14
- #
15
-
16
- include Entity
17
- include ServerNamedEntity
18
- extend ProtocolMethodHandlers
19
-
20
-
21
- #
22
- # API
23
- #
24
-
25
- # Qeueue name. May be server-generated or assigned directly.
26
- attr_reader :name
27
-
28
- # Channel this queue belongs to.
29
- attr_reader :channel
30
-
31
- # Consumer tag identifies subscription for message delivery. It is nil for queues that are not subscribed for messages. See AMQ::Client::Queue#subscribe.
32
- attr_reader :consumer_tag
33
-
34
- # @param [AMQ::Client::Adapter] AMQ networking adapter to use.
35
- # @param [AMQ::Client::Channel] AMQ channel this queue object uses.
36
- # @param [String] Queue name. Please note that AMQP spec does not require brokers to support Unicode for queue names.
37
- # @api public
38
- def initialize(connection, channel, name = AMQ::Protocol::EMPTY_STRING)
39
- raise ArgumentError.new("queue name must not be nil; if you want broker to generate queue name for you, pass an empty string") if name.nil?
40
-
41
- super(connection)
42
-
43
- @name = name
44
- @channel = channel
45
- end
46
-
47
- def dup
48
- if @name.empty?
49
- raise RuntimeError.new("You can't clone anonymous queue until it receives server-generated name. Move the code with #dup to the callback for the #declare method.")
50
- end
51
-
52
- o = super
53
- o.reset_consumer_tag!
54
- o
55
- end
56
-
57
-
58
- # @return [Boolean] true if this queue was declared as durable (will survive broker restart).
59
- # @api public
60
- def durable?
61
- @durable
62
- end # durable?
63
-
64
- # @return [Boolean] true if this queue was declared as exclusive (limited to just one consumer)
65
- # @api public
66
- def exclusive?
67
- @exclusive
68
- end # exclusive?
69
-
70
- # @return [Boolean] true if this queue was declared as automatically deleted (deleted as soon as last consumer unbinds).
71
- # @api public
72
- def auto_delete?
73
- @auto_delete
74
- end # auto_delete?
75
-
76
-
77
- # Declares this queue.
78
- #
79
- #
80
- # @return [Queue] self
81
- #
82
- # @api public
83
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.7.2.1.)
84
- def declare(passive = false, durable = false, exclusive = false, auto_delete = false, nowait = false, arguments = nil, &block)
85
- raise ArgumentError, "declaration with nowait does not make sense for server-named queues! Either specify name other than empty string or use #declare without nowait" if nowait && self.anonymous?
86
-
87
- @durable = durable
88
- @exclusive = exclusive
89
- @auto_delete = auto_delete
90
-
91
- nowait = true if !block && !@name.empty?
92
- @connection.send_frame(Protocol::Queue::Declare.encode(@channel.id, @name, passive, durable, exclusive, auto_delete, nowait, arguments))
93
-
94
- if !nowait
95
- self.append_callback(:declare, &block)
96
- @channel.queues_awaiting_declare_ok.push(self)
97
- end
98
-
99
- self
100
- end
101
-
102
- # Deletes this queue.
103
- #
104
- # @param [Boolean] if_unused delete only if queue has no consumers (subscribers).
105
- # @param [Boolean] if_empty delete only if queue has no messages in it.
106
- # @param [Boolean] nowait Don't wait for reply from broker.
107
- # @return [Queue] self
108
- #
109
- # @api public
110
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.7.2.9.)
111
- def delete(if_unused = false, if_empty = false, nowait = false, &block)
112
- nowait = true unless block
113
- @connection.send_frame(Protocol::Queue::Delete.encode(@channel.id, @name, if_unused, if_empty, nowait))
114
-
115
- if !nowait
116
- self.append_callback(:delete, &block)
117
-
118
- # TODO: delete itself from queues cache
119
- @channel.queues_awaiting_delete_ok.push(self)
120
- end
121
-
122
- self
123
- end # delete(channel, queue, if_unused, if_empty, nowait, &block)
124
-
125
- #
126
- # @return [Queue] self
127
- #
128
- # @api public
129
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.7.2.3.)
130
- def bind(exchange, routing_key = AMQ::Protocol::EMPTY_STRING, nowait = false, arguments = nil, &block)
131
- nowait = true unless block
132
- exchange_name = if exchange.respond_to?(:name)
133
- exchange.name
134
- else
135
-
136
- exchange
137
- end
138
-
139
- @connection.send_frame(Protocol::Queue::Bind.encode(@channel.id, @name, exchange_name, routing_key, nowait, arguments))
140
-
141
- if !nowait
142
- self.append_callback(:bind, &block)
143
-
144
- # TODO: handle channel & connection-level exceptions
145
- @channel.queues_awaiting_bind_ok.push(self)
146
- end
147
-
148
- self
149
- end
150
-
151
- #
152
- # @return [Queue] self
153
- #
154
- # @api public
155
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.7.2.5.)
156
- def unbind(exchange, routing_key = AMQ::Protocol::EMPTY_STRING, arguments = nil, &block)
157
- exchange_name = if exchange.respond_to?(:name)
158
- exchange.name
159
- else
160
-
161
- exchange
162
- end
163
-
164
- @connection.send_frame(Protocol::Queue::Unbind.encode(@channel.id, @name, exchange_name, routing_key, arguments))
165
-
166
- self.append_callback(:unbind, &block)
167
- # TODO: handle channel & connection-level exceptions
168
- @channel.queues_awaiting_unbind_ok.push(self)
169
-
170
- self
171
- end
172
-
173
-
174
- #
175
- # @return [Queue] self
176
- #
177
- # @api public
178
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.3.)
179
- def consume(no_ack = false, exclusive = false, nowait = false, no_local = false, arguments = nil, &block)
180
- raise RuntimeError.new("This instance is already being consumed! Create another one using #dup.") if @consumer_tag
181
-
182
- nowait = true unless block
183
- @consumer_tag = generate_consumer_tag(name)
184
- @connection.send_frame(Protocol::Basic::Consume.encode(@channel.id, @name, @consumer_tag, no_local, no_ack, exclusive, nowait, arguments))
185
-
186
- @channel.consumers[@consumer_tag] = self
187
-
188
- if !nowait
189
- # unlike #get, here it is reasonable to expect more than one callback
190
- # so we use #append_callback
191
- self.append_callback(:consume, &block)
192
-
193
- @channel.queues_awaiting_consume_ok.push(self)
194
- end
195
-
196
- self
197
- end
198
-
199
- # Unique string supposed to be used as a consumer tag.
200
- #
201
- # @return [String] Unique string.
202
- # @api plugin
203
- def generate_consumer_tag(name)
204
- "#{name}-#{Time.now.to_i * 1000}-#{Kernel.rand(999_999_999_999)}"
205
- end
206
-
207
- # Resets consumer tag by setting it to nil.
208
- # @return [String] Consumer tag this queue previously used.
209
- #
210
- # @api plugin
211
- def reset_consumer_tag!
212
- ct = @consumer_tag.dup
213
- @consumer_tag = nil
214
-
215
- ct
216
- end
217
-
218
-
219
- #
220
- # @return [Queue] self
221
- #
222
- # @api public
223
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.10.)
224
- def get(no_ack = false, &block)
225
- @connection.send_frame(Protocol::Basic::Get.encode(@channel.id, @name, no_ack))
226
-
227
- # most people only want one callback per #get call. Consider the following example:
228
- #
229
- # 100.times { queue.get { ... } }
230
- #
231
- # most likely you won't expect 100 callback runs per message here. MK.
232
- self.redefine_callback(:get, &block)
233
- @channel.queues_awaiting_get_response.push(self)
234
-
235
- self
236
- end # get(no_ack = false, &block)
237
-
238
- #
239
- # @return [Queue] self
240
- #
241
- # @api public
242
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.5.)
243
- def cancel(nowait = false, &block)
244
- raise "There is no consumer tag for this queue. This usually means that you are trying to unsubscribe a queue that never was subscribed for messages in the first place." if @consumer_tag.nil?
245
-
246
- @connection.send_frame(Protocol::Basic::Cancel.encode(@channel.id, @consumer_tag, nowait))
247
- @consumer_tag = nil
248
- self.clear_callbacks(:delivery)
249
- self.clear_callbacks(:consume)
250
-
251
- if !nowait
252
- self.redefine_callback(:cancel, &block)
253
- @channel.queues_awaiting_cancel_ok.push(self)
254
- end
255
-
256
- self
257
- end # cancel(&block)
258
-
259
- #
260
- # @return [Queue] self
261
- #
262
- # @api public
263
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.7.2.7.)
264
- def purge(nowait = false, &block)
265
- nowait = true unless block
266
- @connection.send_frame(Protocol::Queue::Purge.encode(@channel.id, @name, nowait))
267
-
268
- if !nowait
269
- self.redefine_callback(:purge, &block)
270
- # TODO: handle channel & connection-level exceptions
271
- @channel.queues_awaiting_purge_ok.push(self)
272
- end
273
-
274
- self
275
- end # purge(nowait = false, &block)
276
-
277
- #
278
- # @return [Queue] self
279
- #
280
- # @api public
281
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.13.)
282
- def acknowledge(delivery_tag)
283
- @channel.acknowledge(delivery_tag)
284
-
285
- self
286
- end # acknowledge(delivery_tag)
287
-
288
- #
289
- # @return [Queue] self
290
- #
291
- # @api public
292
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.14.)
293
- def reject(delivery_tag, requeue = true)
294
- @channel.reject(delivery_tag, requeue)
295
-
296
- self
297
- end # reject(delivery_tag, requeue = true)
298
-
299
-
300
-
301
- # @api public
302
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Sections 1.8.3.9)
303
- def on_delivery(&block)
304
- self.append_callback(:delivery, &block)
305
- end # on_delivery(&block)
306
-
307
-
308
-
309
- #
310
- # Implementation
311
- #
312
-
313
- def handle_declare_ok(method)
314
- @name = method.queue if self.anonymous?
315
- @channel.register_queue(self)
316
-
317
- self.exec_callback_once_yielding_self(:declare, method)
318
- end
319
-
320
- def handle_delete_ok(method)
321
- self.exec_callback_once(:delete, method)
322
- end # handle_delete_ok(method)
323
-
324
- def handle_consume_ok(method)
325
- self.exec_callback_once(:consume, method)
326
- end # handle_consume_ok(method)
327
-
328
- def handle_purge_ok(method)
329
- self.exec_callback_once(:purge, method)
330
- end # handle_purge_ok(method)
331
-
332
- def handle_bind_ok(method)
333
- self.exec_callback_once(:bind, method)
334
- end # handle_bind_ok(method)
335
-
336
- def handle_unbind_ok(method)
337
- self.exec_callback_once(:unbind, method)
338
- end # handle_unbind_ok(method)
339
-
340
- def handle_delivery(method, header, payload)
341
- self.exec_callback(:delivery, method, header, payload)
342
- end # handle_delivery
343
-
344
- def handle_cancel_ok(method)
345
- @consumer_tag = nil
346
- self.exec_callback_once(:cancel, method)
347
- end # handle_cancel_ok(method)
348
-
349
- def handle_get_ok(method, header, payload)
350
- method = Protocol::GetResponse.new(method)
351
- self.exec_callback(:get, method, header, payload)
352
- end # handle_get_ok(method, header, payload)
353
-
354
- def handle_get_empty(method)
355
- method = Protocol::GetResponse.new(method)
356
- self.exec_callback(:get, method)
357
- end # handle_get_empty(method)
358
-
359
-
360
-
361
- # Get the first queue which didn't receive Queue.Declare-Ok yet and run its declare callback.
362
- # The cache includes only queues with {nowait: false}.
363
- self.handle(Protocol::Queue::DeclareOk) do |connection, frame|
364
- method = frame.decode_payload
365
-
366
- channel = connection.channels[frame.channel]
367
- queue = channel.queues_awaiting_declare_ok.shift
368
-
369
- queue.handle_declare_ok(method)
370
- end
371
-
372
-
373
- self.handle(Protocol::Queue::DeleteOk) do |connection, frame|
374
- channel = connection.channels[frame.channel]
375
- queue = channel.queues_awaiting_delete_ok.shift
376
- queue.handle_delete_ok(frame.decode_payload)
377
- end
378
-
379
-
380
- self.handle(Protocol::Queue::BindOk) do |connection, frame|
381
- channel = connection.channels[frame.channel]
382
- queue = channel.queues_awaiting_bind_ok.shift
383
-
384
- queue.handle_bind_ok(frame.decode_payload)
385
- end
386
-
387
-
388
- self.handle(Protocol::Queue::UnbindOk) do |connection, frame|
389
- channel = connection.channels[frame.channel]
390
- queue = channel.queues_awaiting_unbind_ok.shift
391
-
392
- queue.handle_unbind_ok(frame.decode_payload)
393
- end
394
-
395
-
396
- self.handle(Protocol::Basic::ConsumeOk) do |connection, frame|
397
- channel = connection.channels[frame.channel]
398
- queue = channel.queues_awaiting_consume_ok.shift
399
-
400
- queue.handle_consume_ok(frame.decode_payload)
401
- end
402
-
403
-
404
- self.handle(Protocol::Basic::CancelOk) do |connection, frame|
405
- channel = connection.channels[frame.channel]
406
- queue = channel.queues_awaiting_cancel_ok.shift
407
-
408
- queue.handle_consume_ok(frame.decode_payload)
409
- end
410
-
411
-
412
- # Basic.Deliver
413
- self.handle(Protocol::Basic::Deliver) do |connection, method_frame, content_frames|
414
- channel = connection.channels[method_frame.channel]
415
- method = method_frame.decode_payload
416
- queue = channel.consumers[method.consumer_tag]
417
-
418
- header = content_frames.shift
419
- body = content_frames.map { |frame| frame.payload }.join
420
- queue.handle_delivery(method, header, body)
421
- # TODO: ack if necessary
422
- end
423
-
424
-
425
- self.handle(Protocol::Queue::PurgeOk) do |connection, frame|
426
- channel = connection.channels[frame.channel]
427
- queue = channel.queues_awaiting_purge_ok.shift
428
-
429
- queue.handle_purge_ok(frame.decode_payload)
430
- end
431
-
432
-
433
- self.handle(Protocol::Basic::GetOk) do |connection, frame, content_frames|
434
- channel = connection.channels[frame.channel]
435
- queue = channel.queues_awaiting_get_response.shift
436
- method = frame.decode_payload
437
-
438
- header = content_frames.shift
439
- body = content_frames.map {|frame| frame.payload }.join
440
-
441
- queue.handle_get_ok(method, header, body) if queue
442
- end
443
-
444
-
445
- self.handle(Protocol::Basic::GetEmpty) do |connection, frame|
446
- channel = connection.channels[frame.channel]
447
- queue = channel.queues_awaiting_get_response.shift
448
-
449
- queue.handle_get_empty(frame.decode_payload)
450
- end
451
- end # Queue
452
- end # Client
453
- end # AMQ
5
+ Queue = Async::Queue
6
+ end
7
+ end
8
+