amq-client 1.0.4 → 1.1.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|