amq-client 1.0.4 → 1.1.0.pre1
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/Gemfile +4 -7
- data/README.textile +2 -11
- data/amq-client.gemspec +1 -1
- data/lib/amq/client/async/channel.rb +170 -5
- data/lib/amq/client/async/consumer.rb +20 -0
- data/lib/amq/client/async/extensions/rabbitmq/basic.rb +0 -19
- data/lib/amq/client/async/extensions/rabbitmq/cancel.rb +0 -36
- data/lib/amq/client/async/extensions/rabbitmq/confirm.rb +0 -216
- data/lib/amq/client/async/queue.rb +5 -0
- data/lib/amq/client/settings.rb +18 -2
- data/lib/amq/client/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e048fd0f6f2ca40b06451aa3d1cef036e9cde06d
|
4
|
+
data.tar.gz: 3e8199a4a282820d296d7db07074390ca1a84414
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b49835db84d478c254ff8a407fe41f569e2b1fc1b8bed77fb6cfb16bb4b21cfa2002d4af5fa35352b9f7848013c10f0d68bec473d3f27b6bba6a6544ad790a3a
|
7
|
+
data.tar.gz: 48942317ed76658d144311fa07990ff4c61f0b35f3a55f638908d2e746f86312cae05d5b73178f639da67935453291de8a2d261263958b76bb7f56ec4b9f498c
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0@amqp
|
data/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
source
|
3
|
+
source "https://rubygems.org"
|
4
4
|
|
5
5
|
# Use local clones if possible.
|
6
6
|
# If you want to use your local copy, just symlink it to vendor.
|
@@ -20,7 +20,7 @@ extend Module.new {
|
|
20
20
|
end
|
21
21
|
}
|
22
22
|
|
23
|
-
gem "eventmachine"
|
23
|
+
gem "eventmachine", ">= 1.0.0"
|
24
24
|
# cool.io uses iobuffer that won't compile on JRuby
|
25
25
|
# (and, probably, Windows)
|
26
26
|
gem "cool.io", :platform => :ruby
|
@@ -30,14 +30,11 @@ group :development do
|
|
30
30
|
gem "yard"
|
31
31
|
# yard tags this buddy along
|
32
32
|
gem "RedCloth", :platform => :mri
|
33
|
-
|
34
|
-
gem "nake", :platform => :ruby_19
|
35
|
-
# excludes Windows and JRuby
|
36
|
-
gem "perftools.rb", :platform => :mri
|
37
33
|
end
|
38
34
|
|
39
35
|
group :test do
|
40
|
-
gem "
|
36
|
+
gem "rake", ">= 10.0.3"
|
37
|
+
gem "rspec", ">= 2.13.0"
|
41
38
|
gem "evented-spec", :git => "git://github.com/ruby-amqp/evented-spec.git", :branch => "master"
|
42
39
|
gem "effin_utf8"
|
43
40
|
|
data/README.textile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
h2. About amq-client
|
2
2
|
|
3
|
-
amq-client is a fully-featured, low-level AMQP 0.9.1 client that runs on Ruby 1.
|
3
|
+
amq-client is a fully-featured, low-level AMQP 0.9.1 client that runs on Ruby 1.9.3, 1.9.2, Rubinius 2, JRuby, 1.8.7 and REE.
|
4
4
|
It's sweet spot is in serving as foundation for higher-level, more opinionated AMQP libraries.
|
5
5
|
It can be used directly by applications code when performance and access to
|
6
6
|
advanced AMQP protocol features is more important that API convenience.
|
@@ -53,20 +53,11 @@ amq-client is available from rubygems.org:
|
|
53
53
|
If you use Bundler and want to use the very latest version, add this to your Gemfile:
|
54
54
|
<pre>
|
55
55
|
<code>
|
56
|
-
gem "amq-client",
|
56
|
+
gem "amq-client", "~> 1.0.0"
|
57
57
|
</code>
|
58
58
|
</pre>
|
59
59
|
|
60
60
|
|
61
|
-
h2. Pre-prelease versions
|
62
|
-
|
63
|
-
Pre-release versions are available from rubygems.org:
|
64
|
-
|
65
|
-
<pre>
|
66
|
-
gem install amq-client --pre
|
67
|
-
</pre>
|
68
|
-
|
69
|
-
|
70
61
|
h2. See also
|
71
62
|
|
72
63
|
* "API documentation":http://rdoc.info/github/ruby-amqp/amq-client/master/frames
|
data/amq-client.gemspec
CHANGED
@@ -35,6 +35,14 @@ module AMQ
|
|
35
35
|
|
36
36
|
attr_accessor :flow_is_active
|
37
37
|
|
38
|
+
# Change publisher index. Publisher index is incremented
|
39
|
+
# by 1 after each Basic.Publish starting at 1. This is done
|
40
|
+
# on both client and server, hence this acknowledged messages
|
41
|
+
# can be matched via its delivery-tag.
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
attr_writer :publisher_index
|
45
|
+
|
38
46
|
|
39
47
|
def initialize(connection, id, options = {})
|
40
48
|
super(connection)
|
@@ -140,15 +148,20 @@ module AMQ
|
|
140
148
|
self
|
141
149
|
end # acknowledge(delivery_tag, multiple = false)
|
142
150
|
|
143
|
-
# Reject a message with given delivery tag.
|
151
|
+
# Reject a message with given delivery tag. When rejecting multiple messages at once,
|
152
|
+
# uses back.nack instead of basic.reject.
|
144
153
|
#
|
145
154
|
# @api public
|
146
|
-
# @see
|
147
|
-
def reject(delivery_tag, requeue = true)
|
148
|
-
|
155
|
+
# @see http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack
|
156
|
+
def reject(delivery_tag, requeue = true, multi = false)
|
157
|
+
if multi
|
158
|
+
@connection.send_frame(Protocol::Basic::Nack.encode(self.id, delivery_tag, multi, requeue))
|
159
|
+
else
|
160
|
+
@connection.send_frame(Protocol::Basic::Reject.encode(self.id, delivery_tag, requeue))
|
161
|
+
end
|
149
162
|
|
150
163
|
self
|
151
|
-
end # reject
|
164
|
+
end # reject
|
152
165
|
|
153
166
|
# Notifies AMQ broker that consumer has recovered and unacknowledged messages need
|
154
167
|
# to be redelivered.
|
@@ -332,6 +345,139 @@ module AMQ
|
|
332
345
|
# @endgroup
|
333
346
|
|
334
347
|
|
348
|
+
# Publisher index is an index of the last message since
|
349
|
+
# the confirmations were activated, started with 0. It's
|
350
|
+
# incremented by 1 every time a message is published.
|
351
|
+
# This is done on both client and server, hence this
|
352
|
+
# acknowledged messages can be matched via its delivery-tag.
|
353
|
+
#
|
354
|
+
# @return [Integer] Current publisher index.
|
355
|
+
# @api public
|
356
|
+
def publisher_index
|
357
|
+
@publisher_index ||= 0
|
358
|
+
end
|
359
|
+
|
360
|
+
# Resets publisher index to 0
|
361
|
+
#
|
362
|
+
# @api plugin
|
363
|
+
def reset_publisher_index!
|
364
|
+
@publisher_index = 0
|
365
|
+
end
|
366
|
+
|
367
|
+
|
368
|
+
# This method is executed after publishing of each message via {Exchage#publish}.
|
369
|
+
# Currently it just increments publisher index by 1, so messages
|
370
|
+
# can be actually matched.
|
371
|
+
#
|
372
|
+
# @api plugin
|
373
|
+
def increment_publisher_index!
|
374
|
+
@publisher_index += 1
|
375
|
+
end
|
376
|
+
|
377
|
+
# Turn on confirmations for this channel and, if given,
|
378
|
+
# register callback for Confirm.Select-Ok.
|
379
|
+
#
|
380
|
+
# @raise [RuntimeError] Occurs when confirmations are already activated.
|
381
|
+
# @raise [RuntimeError] Occurs when nowait is true and block is given.
|
382
|
+
#
|
383
|
+
# @param [Boolean] nowait Whether we expect Confirm.Select-Ok to be returned by the broker or not.
|
384
|
+
# @yield [method] Callback which will be executed once we receive Confirm.Select-Ok.
|
385
|
+
# @yieldparam [AMQ::Protocol::Confirm::SelectOk] method Protocol method class instance.
|
386
|
+
#
|
387
|
+
# @return [self] self.
|
388
|
+
#
|
389
|
+
# @see #confirm
|
390
|
+
def confirm_select(nowait = false, &block)
|
391
|
+
if nowait && block
|
392
|
+
raise ArgumentError, "confirm.select with nowait = true and a callback makes no sense"
|
393
|
+
end
|
394
|
+
|
395
|
+
@uses_publisher_confirmations = true
|
396
|
+
reset_publisher_index!
|
397
|
+
|
398
|
+
self.redefine_callback(:confirm_select, &block) unless nowait
|
399
|
+
self.redefine_callback(:after_publish) do
|
400
|
+
increment_publisher_index!
|
401
|
+
end
|
402
|
+
@connection.send_frame(Protocol::Confirm::Select.encode(@id, nowait))
|
403
|
+
|
404
|
+
self
|
405
|
+
end
|
406
|
+
|
407
|
+
# @return [Boolean]
|
408
|
+
def uses_publisher_confirmations?
|
409
|
+
@uses_publisher_confirmations
|
410
|
+
end # uses_publisher_confirmations?
|
411
|
+
|
412
|
+
|
413
|
+
# Turn on confirmations for this channel and, if given,
|
414
|
+
# register callback for basic.ack from the broker.
|
415
|
+
#
|
416
|
+
# @raise [RuntimeError] Occurs when confirmations are already activated.
|
417
|
+
# @raise [RuntimeError] Occurs when nowait is true and block is given.
|
418
|
+
# @param [Boolean] nowait Whether we expect Confirm.Select-Ok to be returned by the broker or not.
|
419
|
+
#
|
420
|
+
# @yield [basick_ack] Callback which will be executed every time we receive Basic.Ack from the broker.
|
421
|
+
# @yieldparam [AMQ::Protocol::Basic::Ack] basick_ack Protocol method class instance.
|
422
|
+
#
|
423
|
+
# @return [self] self.
|
424
|
+
def on_ack(nowait = false, &block)
|
425
|
+
self.use_publisher_confirmations! unless self.uses_publisher_confirmations?
|
426
|
+
|
427
|
+
self.define_callback(:ack, &block) if block
|
428
|
+
|
429
|
+
self
|
430
|
+
end
|
431
|
+
|
432
|
+
|
433
|
+
# Register error callback for Basic.Nack. It's called
|
434
|
+
# when message(s) is rejected.
|
435
|
+
#
|
436
|
+
# @return [self] self
|
437
|
+
def on_nack(&block)
|
438
|
+
self.define_callback(:nack, &block) if block
|
439
|
+
|
440
|
+
self
|
441
|
+
end
|
442
|
+
|
443
|
+
|
444
|
+
|
445
|
+
|
446
|
+
# Handler for Confirm.Select-Ok. By default, it just
|
447
|
+
# executes hook specified via the #confirmations method
|
448
|
+
# with a single argument, a protocol method class
|
449
|
+
# instance (an instance of AMQ::Protocol::Confirm::SelectOk)
|
450
|
+
# and then it deletes the callback, since Confirm.Select
|
451
|
+
# is supposed to be sent just once.
|
452
|
+
#
|
453
|
+
# @api plugin
|
454
|
+
def handle_select_ok(method)
|
455
|
+
self.exec_callback_once(:confirm_select, method)
|
456
|
+
end
|
457
|
+
|
458
|
+
# Handler for Basic.Ack. By default, it just
|
459
|
+
# executes hook specified via the #confirm method
|
460
|
+
# with a single argument, a protocol method class
|
461
|
+
# instance (an instance of AMQ::Protocol::Basic::Ack).
|
462
|
+
#
|
463
|
+
# @api plugin
|
464
|
+
def handle_basic_ack(method)
|
465
|
+
self.exec_callback(:ack, method)
|
466
|
+
end
|
467
|
+
|
468
|
+
|
469
|
+
# Handler for Basic.Nack. By default, it just
|
470
|
+
# executes hook specified via the #confirm_failed method
|
471
|
+
# with a single argument, a protocol method class
|
472
|
+
# instance (an instance of AMQ::Protocol::Basic::Nack).
|
473
|
+
#
|
474
|
+
# @api plugin
|
475
|
+
def handle_basic_nack(method)
|
476
|
+
self.exec_callback(:nack, method)
|
477
|
+
end
|
478
|
+
|
479
|
+
|
480
|
+
|
335
481
|
#
|
336
482
|
# Implementation
|
337
483
|
#
|
@@ -390,6 +536,7 @@ module AMQ
|
|
390
536
|
@queues_awaiting_get_response = Array.new
|
391
537
|
|
392
538
|
@callbacks = @callbacks.delete_if { |k, v| !RECOVERY_EVENTS.include?(k) }
|
539
|
+
@uses_publisher_confirmations = false
|
393
540
|
end # reset_state!
|
394
541
|
|
395
542
|
|
@@ -473,6 +620,24 @@ module AMQ
|
|
473
620
|
channel = connection.channels[frame.channel]
|
474
621
|
channel.exec_callback(:tx_rollback, frame.decode_payload)
|
475
622
|
end
|
623
|
+
|
624
|
+
self.handle(Protocol::Confirm::SelectOk) do |connection, frame|
|
625
|
+
method = frame.decode_payload
|
626
|
+
channel = connection.channels[frame.channel]
|
627
|
+
channel.handle_select_ok(method)
|
628
|
+
end
|
629
|
+
|
630
|
+
self.handle(Protocol::Basic::Ack) do |connection, frame|
|
631
|
+
method = frame.decode_payload
|
632
|
+
channel = connection.channels[frame.channel]
|
633
|
+
channel.handle_basic_ack(method)
|
634
|
+
end
|
635
|
+
|
636
|
+
self.handle(Protocol::Basic::Nack) do |connection, frame|
|
637
|
+
method = frame.decode_payload
|
638
|
+
channel = connection.channels[frame.channel]
|
639
|
+
channel.handle_basic_nack(method)
|
640
|
+
end
|
476
641
|
end # Channel
|
477
642
|
end # Async
|
478
643
|
end # Client
|
@@ -97,6 +97,17 @@ module AMQ
|
|
97
97
|
end # cancel(nowait = false, &block)
|
98
98
|
|
99
99
|
|
100
|
+
def on_cancel(&block)
|
101
|
+
self.append_callback(:scancel, &block)
|
102
|
+
|
103
|
+
self
|
104
|
+
end # on_cancel(&block)
|
105
|
+
|
106
|
+
def handle_cancel(basic_cancel)
|
107
|
+
self.exec_callback(:scancel, basic_cancel)
|
108
|
+
end # handle_cancel(basic_cancel)
|
109
|
+
|
110
|
+
|
100
111
|
|
101
112
|
def on_delivery(&block)
|
102
113
|
self.append_callback(:delivery, &block)
|
@@ -270,6 +281,15 @@ module AMQ
|
|
270
281
|
def unregister_with_queue
|
271
282
|
@queue.consumers.delete(@consumer_tag)
|
272
283
|
end # register_with_queue
|
284
|
+
|
285
|
+
handle(Protocol::Basic::Cancel) do |connection, method_frame|
|
286
|
+
channel = connection.channels[method_frame.channel]
|
287
|
+
basic_cancel = method_frame.decode_payload
|
288
|
+
consumer = channel.consumers[basic_cancel.consumer_tag]
|
289
|
+
|
290
|
+
# Handle the delivery only if the consumer still exists.
|
291
|
+
consumer.handle_cancel(basic_cancel) if consumer
|
292
|
+
end
|
273
293
|
end # Consumer
|
274
294
|
end # Async
|
275
295
|
end # Client
|
@@ -10,29 +10,10 @@ module AMQ
|
|
10
10
|
module RabbitMQ
|
11
11
|
module Basic
|
12
12
|
module ChannelMixin
|
13
|
-
|
14
|
-
# Overrides {AMQ::Client::Channel#reject} behavior to use basic.nack.
|
15
|
-
#
|
16
|
-
# @api public
|
17
|
-
# @see http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack
|
18
|
-
def reject(delivery_tag, requeue = true, multi = false)
|
19
|
-
if multi
|
20
|
-
@connection.send_frame(Protocol::Basic::Nack.encode(self.id, delivery_tag, multi, requeue))
|
21
|
-
else
|
22
|
-
super(delivery_tag, requeue)
|
23
|
-
end
|
24
|
-
end # reject
|
25
|
-
|
26
13
|
end # ChannelMixin
|
27
14
|
end # Basic
|
28
15
|
end # RabbitMQ
|
29
16
|
end # Extensions
|
30
|
-
|
31
|
-
class Channel
|
32
|
-
# use modules, the native Ruby way of extension of existing classes,
|
33
|
-
# instead of reckless monkey-patching. MK.
|
34
|
-
include Extensions::RabbitMQ::Basic::ChannelMixin
|
35
|
-
end # Channel
|
36
17
|
end # Async
|
37
18
|
end # Client
|
38
19
|
end # AMQ
|
@@ -10,50 +10,14 @@ module AMQ
|
|
10
10
|
module RabbitMQ
|
11
11
|
module Basic
|
12
12
|
module ConsumerMixin
|
13
|
-
|
14
|
-
def on_cancel(&block)
|
15
|
-
self.append_callback(:scancel, &block)
|
16
|
-
|
17
|
-
self
|
18
|
-
end # on_cancel(&block)
|
19
|
-
|
20
|
-
def handle_cancel(basic_cancel)
|
21
|
-
self.exec_callback(:scancel, basic_cancel)
|
22
|
-
end # handle_cancel(basic_cancel)
|
23
|
-
|
24
|
-
def self.included receiver
|
25
|
-
receiver.handle(Protocol::Basic::Cancel) do |connection, method_frame|
|
26
|
-
channel = connection.channels[method_frame.channel]
|
27
|
-
basic_cancel = method_frame.decode_payload
|
28
|
-
consumer = channel.consumers[basic_cancel.consumer_tag]
|
29
|
-
|
30
|
-
# Handle the delivery only if the consumer still exists.
|
31
|
-
consumer.handle_cancel(basic_cancel) if consumer
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
13
|
end # ConsumerMixin
|
36
14
|
|
37
15
|
module QueueMixin
|
38
|
-
|
39
|
-
# @api public
|
40
|
-
def on_cancel(&block)
|
41
|
-
@default_consumer.on_cancel(&block)
|
42
|
-
end # on_cancel(&block)
|
43
16
|
end
|
44
17
|
|
45
18
|
end # Basic
|
46
19
|
end # RabbitMQ
|
47
20
|
end # Extensions
|
48
|
-
|
49
|
-
class Consumer
|
50
|
-
include Extensions::RabbitMQ::Basic::ConsumerMixin
|
51
|
-
end # Consumer
|
52
|
-
|
53
|
-
class Queue
|
54
|
-
include Extensions::RabbitMQ::Basic::QueueMixin
|
55
|
-
end # Queue
|
56
|
-
|
57
21
|
end # Async
|
58
22
|
end # Client
|
59
23
|
end # AMQ
|
@@ -5,226 +5,10 @@ module AMQ
|
|
5
5
|
module Async
|
6
6
|
module Extensions
|
7
7
|
module RabbitMQ
|
8
|
-
# h2. Purpose
|
9
|
-
# In case that the broker crashes, some messages can get lost.
|
10
|
-
# Thanks to this extension, broker sends Basic.Ack when the message
|
11
|
-
# is processed by the broker. In case of persistent messages, it must
|
12
|
-
# be written to disk or ack'd on all the queues it was delivered to.
|
13
|
-
# However it doesn't have to be necessarily 1:1, because the broker
|
14
|
-
# can send Basic.Ack with multi flag to acknowledge multiple messages.
|
15
|
-
#
|
16
|
-
# So it provides clients a lightweight way of keeping track of which
|
17
|
-
# messages have been processed by the broker and which would need
|
18
|
-
# re-publishing in case of broker shutdown or network failure.
|
19
|
-
#
|
20
|
-
# Transactions are solving the same problem, but they are very slow:
|
21
|
-
# confirmations are more than 100 times faster.
|
22
|
-
#
|
23
|
-
# h2. Workflow
|
24
|
-
# * Client asks broker to confirm messages on given channel (Confirm.Select).
|
25
|
-
# * Broker sends back Confirm.Select-Ok, unless we sent Confirm.Select with nowait=true.
|
26
|
-
# * After each published message, the client receives Basic.Ack from the broker.
|
27
|
-
# * If something bad happens inside the broker, it sends Basic.Nack.
|
28
|
-
#
|
29
|
-
# h2. Gotchas
|
30
|
-
# Note that we don't keep track of messages awaiting confirmation.
|
31
|
-
# It'd add a huge overhead and it's impossible to come up with one-suits-all solution.
|
32
|
-
# If you want to create such module, you'll probably want to redefine Channel#after_publish,
|
33
|
-
# so it will put messages into a queue and then handlers for Basic.Ack and Basic.Nack.
|
34
|
-
# This is the reason why we pass every argument from Exchange#publish to Channel#after_publish.
|
35
|
-
# You should not forget though, that both of these methods can have multi flag!
|
36
|
-
#
|
37
|
-
# Transactional channel cannot be put into confirm mode and a confirm
|
38
|
-
# mode channel cannot be made transactional.
|
39
|
-
#
|
40
|
-
# If the connection between the publisher and broker drops with outstanding
|
41
|
-
# confirms, it does not necessarily mean that the messages were lost, so
|
42
|
-
# republishing may result in duplicate messages.
|
43
|
-
|
44
|
-
# h2. Learn more
|
45
|
-
# @see http://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms
|
46
|
-
# @see http://www.rabbitmq.com/amqp-0-9-1-quickref.html#class.confirm
|
47
|
-
# @see http://www.rabbitmq.com/amqp-0-9-1-reference.html#basic.ack
|
48
8
|
module Confirm
|
49
|
-
module ChannelMixin
|
50
|
-
|
51
|
-
# Change publisher index. Publisher index is incremented
|
52
|
-
# by 1 after each Basic.Publish starting at 1. This is done
|
53
|
-
# on both client and server, hence this acknowledged messages
|
54
|
-
# can be matched via its delivery-tag.
|
55
|
-
#
|
56
|
-
# @api private
|
57
|
-
attr_writer :publisher_index
|
58
|
-
|
59
|
-
# Publisher index is an index of the last message since
|
60
|
-
# the confirmations were activated, started with 0. It's
|
61
|
-
# incremented by 1 every time a message is published.
|
62
|
-
# This is done on both client and server, hence this
|
63
|
-
# acknowledged messages can be matched via its delivery-tag.
|
64
|
-
#
|
65
|
-
# @return [Integer] Current publisher index.
|
66
|
-
# @api public
|
67
|
-
def publisher_index
|
68
|
-
@publisher_index ||= 0
|
69
|
-
end
|
70
|
-
|
71
|
-
# Resets publisher index to 0
|
72
|
-
#
|
73
|
-
# @api plugin
|
74
|
-
def reset_publisher_index!
|
75
|
-
@publisher_index = 0
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
# This method is executed after publishing of each message via {Exchage#publish}.
|
80
|
-
# Currently it just increments publisher index by 1, so messages
|
81
|
-
# can be actually matched.
|
82
|
-
#
|
83
|
-
# @api plugin
|
84
|
-
def increment_publisher_index!
|
85
|
-
@publisher_index += 1
|
86
|
-
end
|
87
|
-
|
88
|
-
# Turn on confirmations for this channel and, if given,
|
89
|
-
# register callback for Confirm.Select-Ok.
|
90
|
-
#
|
91
|
-
# @raise [RuntimeError] Occurs when confirmations are already activated.
|
92
|
-
# @raise [RuntimeError] Occurs when nowait is true and block is given.
|
93
|
-
#
|
94
|
-
# @param [Boolean] nowait Whether we expect Confirm.Select-Ok to be returned by the broker or not.
|
95
|
-
# @yield [method] Callback which will be executed once we receive Confirm.Select-Ok.
|
96
|
-
# @yieldparam [AMQ::Protocol::Confirm::SelectOk] method Protocol method class instance.
|
97
|
-
#
|
98
|
-
# @return [self] self.
|
99
|
-
#
|
100
|
-
# @see #confirm
|
101
|
-
def confirm_select(nowait = false, &block)
|
102
|
-
if nowait && block
|
103
|
-
raise ArgumentError, "confirm.select with nowait = true and a callback makes no sense"
|
104
|
-
end
|
105
|
-
|
106
|
-
@uses_publisher_confirmations = true
|
107
|
-
reset_publisher_index!
|
108
|
-
|
109
|
-
self.redefine_callback(:confirm_select, &block) unless nowait
|
110
|
-
self.redefine_callback(:after_publish) do
|
111
|
-
increment_publisher_index!
|
112
|
-
end
|
113
|
-
@connection.send_frame(Protocol::Confirm::Select.encode(@id, nowait))
|
114
|
-
|
115
|
-
self
|
116
|
-
end
|
117
|
-
|
118
|
-
# @return [Boolean]
|
119
|
-
def uses_publisher_confirmations?
|
120
|
-
@uses_publisher_confirmations
|
121
|
-
end # uses_publisher_confirmations?
|
122
|
-
|
123
|
-
|
124
|
-
# Turn on confirmations for this channel and, if given,
|
125
|
-
# register callback for basic.ack from the broker.
|
126
|
-
#
|
127
|
-
# @raise [RuntimeError] Occurs when confirmations are already activated.
|
128
|
-
# @raise [RuntimeError] Occurs when nowait is true and block is given.
|
129
|
-
# @param [Boolean] nowait Whether we expect Confirm.Select-Ok to be returned by the broker or not.
|
130
|
-
#
|
131
|
-
# @yield [basick_ack] Callback which will be executed every time we receive Basic.Ack from the broker.
|
132
|
-
# @yieldparam [AMQ::Protocol::Basic::Ack] basick_ack Protocol method class instance.
|
133
|
-
#
|
134
|
-
# @return [self] self.
|
135
|
-
def on_ack(nowait = false, &block)
|
136
|
-
self.use_publisher_confirmations! unless self.uses_publisher_confirmations?
|
137
|
-
|
138
|
-
self.define_callback(:ack, &block) if block
|
139
|
-
|
140
|
-
self
|
141
|
-
end
|
142
|
-
|
143
|
-
|
144
|
-
# Register error callback for Basic.Nack. It's called
|
145
|
-
# when message(s) is rejected.
|
146
|
-
#
|
147
|
-
# @return [self] self
|
148
|
-
def on_nack(&block)
|
149
|
-
self.define_callback(:nack, &block) if block
|
150
|
-
|
151
|
-
self
|
152
|
-
end
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
# Handler for Confirm.Select-Ok. By default, it just
|
158
|
-
# executes hook specified via the #confirmations method
|
159
|
-
# with a single argument, a protocol method class
|
160
|
-
# instance (an instance of AMQ::Protocol::Confirm::SelectOk)
|
161
|
-
# and then it deletes the callback, since Confirm.Select
|
162
|
-
# is supposed to be sent just once.
|
163
|
-
#
|
164
|
-
# @api plugin
|
165
|
-
def handle_select_ok(method)
|
166
|
-
self.exec_callback_once(:confirm_select, method)
|
167
|
-
end
|
168
|
-
|
169
|
-
# Handler for Basic.Ack. By default, it just
|
170
|
-
# executes hook specified via the #confirm method
|
171
|
-
# with a single argument, a protocol method class
|
172
|
-
# instance (an instance of AMQ::Protocol::Basic::Ack).
|
173
|
-
#
|
174
|
-
# @api plugin
|
175
|
-
def handle_basic_ack(method)
|
176
|
-
self.exec_callback(:ack, method)
|
177
|
-
end
|
178
|
-
|
179
|
-
|
180
|
-
# Handler for Basic.Nack. By default, it just
|
181
|
-
# executes hook specified via the #confirm_failed method
|
182
|
-
# with a single argument, a protocol method class
|
183
|
-
# instance (an instance of AMQ::Protocol::Basic::Nack).
|
184
|
-
#
|
185
|
-
# @api plugin
|
186
|
-
def handle_basic_nack(method)
|
187
|
-
self.exec_callback(:nack, method)
|
188
|
-
end
|
189
|
-
|
190
|
-
|
191
|
-
def reset_state!
|
192
|
-
super
|
193
|
-
|
194
|
-
@uses_publisher_confirmations = false
|
195
|
-
end
|
196
|
-
|
197
|
-
|
198
|
-
def self.included(host)
|
199
|
-
host.handle(Protocol::Confirm::SelectOk) do |connection, frame|
|
200
|
-
method = frame.decode_payload
|
201
|
-
channel = connection.channels[frame.channel]
|
202
|
-
channel.handle_select_ok(method)
|
203
|
-
end
|
204
|
-
|
205
|
-
host.handle(Protocol::Basic::Ack) do |connection, frame|
|
206
|
-
method = frame.decode_payload
|
207
|
-
channel = connection.channels[frame.channel]
|
208
|
-
channel.handle_basic_ack(method)
|
209
|
-
end
|
210
|
-
|
211
|
-
host.handle(Protocol::Basic::Nack) do |connection, frame|
|
212
|
-
method = frame.decode_payload
|
213
|
-
channel = connection.channels[frame.channel]
|
214
|
-
channel.handle_basic_nack(method)
|
215
|
-
end
|
216
|
-
end # self.included(host)
|
217
|
-
end # ChannelMixin
|
218
9
|
end # Confirm
|
219
10
|
end # RabbitMQ
|
220
11
|
end # Extensions
|
221
|
-
|
222
|
-
|
223
|
-
class Channel
|
224
|
-
# use modules, a native Ruby way of extension of existing classes,
|
225
|
-
# instead of reckless monkey-patching. MK.
|
226
|
-
include Extensions::RabbitMQ::Confirm::ChannelMixin
|
227
|
-
end # Channel
|
228
12
|
end # Async
|
229
13
|
end # Client
|
230
14
|
end # AMQ
|
data/lib/amq/client/settings.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require "amq/protocol/client" # TODO: "amq/protocol/constants"
|
4
|
-
require "
|
4
|
+
require "uri"
|
5
5
|
|
6
6
|
module AMQ
|
7
7
|
module Client
|
@@ -136,7 +136,23 @@ module AMQ
|
|
136
136
|
# @see http://bit.ly/ks8MXK Connecting to The Broker documentation guide
|
137
137
|
# @api public
|
138
138
|
def self.parse_amqp_url(connection_string)
|
139
|
-
|
139
|
+
uri = URI.parse(connection_string)
|
140
|
+
raise ArgumentError.new("Connection URI must use amqp or amqps schema (example: amqp://bus.megacorp.internal:5766), learn more at http://bit.ly/ks8MXK") unless %w{amqp amqps}.include?(uri.scheme)
|
141
|
+
|
142
|
+
opts = {}
|
143
|
+
|
144
|
+
opts[:scheme] = uri.scheme
|
145
|
+
opts[:user] = URI.unescape(uri.user) if uri.user
|
146
|
+
opts[:pass] = URI.unescape(uri.password) if uri.password
|
147
|
+
opts[:host] = uri.host if uri.host
|
148
|
+
opts[:port] = uri.port || AMQ::Client::Settings::AMQP_PORTS[uri.scheme]
|
149
|
+
opts[:ssl] = uri.scheme == AMQ::Client::Settings::AMQPS
|
150
|
+
if uri.path =~ %r{^/(.*)}
|
151
|
+
raise ArgumentError.new("#{uri} has multiple-segment path; please percent-encode any slashes in the vhost name (e.g. /production => %2Fproduction). Learn more at http://bit.ly/amqp-gem-and-connection-uris") if $1.index('/')
|
152
|
+
opts[:vhost] = URI.unescape($1)
|
153
|
+
end
|
154
|
+
|
155
|
+
opts
|
140
156
|
end
|
141
157
|
end
|
142
158
|
end
|
data/lib/amq/client/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amq-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.1.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakub Stastny
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-
|
14
|
+
date: 2013-06-25 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: eventmachine
|
@@ -33,14 +33,14 @@ dependencies:
|
|
33
33
|
requirements:
|
34
34
|
- - '>='
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: 1.
|
36
|
+
version: 1.2.0
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - '>='
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.
|
43
|
+
version: 1.2.0
|
44
44
|
description: amq-client is a fully-featured, low-level AMQP 0.9.1 client with pluggable
|
45
45
|
networking I/O adapters (EventMachine, cool.io, Eventpanda and so on) and supposed
|
46
46
|
to back more opinionated AMQP clients (such as amqp gem) or be used directly in
|
@@ -57,6 +57,7 @@ files:
|
|
57
57
|
- .gitignore
|
58
58
|
- .gitmodules
|
59
59
|
- .rspec
|
60
|
+
- .ruby-version
|
60
61
|
- .travis.yml
|
61
62
|
- .yardopts
|
62
63
|
- Gemfile
|
@@ -232,14 +233,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
232
233
|
version: '0'
|
233
234
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
234
235
|
requirements:
|
235
|
-
- - '
|
236
|
+
- - '>'
|
236
237
|
- !ruby/object:Gem::Version
|
237
|
-
version:
|
238
|
+
version: 1.3.1
|
238
239
|
requirements: []
|
239
240
|
rubyforge_project: amq-client
|
240
|
-
rubygems_version: 2.
|
241
|
+
rubygems_version: 2.0.3
|
241
242
|
signing_key:
|
242
243
|
specification_version: 4
|
243
244
|
summary: amq-client is a fully-featured, low-level AMQP 0.9.1 client
|
244
245
|
test_files: []
|
245
|
-
has_rdoc:
|