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.
- data/.travis.yml +4 -0
- data/Gemfile +1 -1
- data/README.textile +1 -1
- data/bin/ci/before_build.sh +24 -0
- data/examples/eventmachine_adapter/extensions/rabbitmq/handling_confirm_select_ok.rb +2 -2
- data/examples/eventmachine_adapter/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +1 -1
- data/examples/eventmachine_adapter/extensions/rabbitmq/publisher_confirmations_with_unroutable_message.rb +1 -1
- data/lib/amq/client.rb +29 -17
- data/lib/amq/client/adapter.rb +8 -504
- data/lib/amq/client/adapters/coolio.rb +4 -282
- data/lib/amq/client/adapters/event_machine.rb +4 -382
- data/lib/amq/client/async/adapter.rb +517 -0
- data/lib/amq/client/async/adapters/coolio.rb +291 -0
- data/lib/amq/client/async/adapters/event_machine.rb +392 -0
- data/lib/amq/client/async/adapters/eventmachine.rb +1 -0
- data/lib/amq/client/async/callbacks.rb +71 -0
- data/lib/amq/client/async/channel.rb +385 -0
- data/lib/amq/client/async/entity.rb +66 -0
- data/lib/amq/client/async/exchange.rb +157 -0
- data/lib/amq/client/async/extensions/rabbitmq/basic.rb +38 -0
- data/lib/amq/client/async/extensions/rabbitmq/confirm.rb +248 -0
- data/lib/amq/client/async/queue.rb +455 -0
- data/lib/amq/client/callbacks.rb +6 -65
- data/lib/amq/client/channel.rb +4 -376
- data/lib/amq/client/entity.rb +6 -57
- data/lib/amq/client/exchange.rb +4 -148
- data/lib/amq/client/extensions/rabbitmq/basic.rb +4 -28
- data/lib/amq/client/extensions/rabbitmq/confirm.rb +5 -240
- data/lib/amq/client/queue.rb +5 -450
- data/lib/amq/client/version.rb +1 -1
- data/spec/unit/client_spec.rb +10 -30
- metadata +16 -22
data/lib/amq/client/entity.rb
CHANGED
@@ -1,64 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require "amq/client/
|
4
|
-
require "amq/client/openable"
|
3
|
+
require "amq/client/async/entity"
|
5
4
|
|
6
5
|
module AMQ
|
7
6
|
module Client
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# # instead of:
|
14
|
-
# channel = Channel.new(client, 1)
|
15
|
-
def register_entity(name, klass)
|
16
|
-
define_method(name) do |*args, &block|
|
17
|
-
klass.new(self, *args, &block)
|
18
|
-
end # define_method
|
19
|
-
end # register_entity
|
20
|
-
end # RegisterEntityMixin
|
21
|
-
|
22
|
-
module ProtocolMethodHandlers
|
23
|
-
def handle(klass, &block)
|
24
|
-
AMQ::Client::HandlersRegistry.register(klass, &block)
|
25
|
-
end
|
26
|
-
|
27
|
-
def handlers
|
28
|
-
AMQ::Client::HandlersRegistry.handlers
|
29
|
-
end
|
30
|
-
end # ProtocolMethodHandlers
|
31
|
-
|
32
|
-
|
33
|
-
# AMQ entities, as implemented by AMQ::Client, have callbacks and can run them
|
34
|
-
# when necessary.
|
35
|
-
#
|
36
|
-
# @note Exchanges and queues implementation is based on this class.
|
37
|
-
#
|
38
|
-
# @abstract
|
39
|
-
module Entity
|
40
|
-
|
41
|
-
#
|
42
|
-
# Behaviors
|
43
|
-
#
|
44
|
-
|
45
|
-
include Openable
|
46
|
-
include Callbacks
|
47
|
-
|
48
|
-
#
|
49
|
-
# API
|
50
|
-
#
|
51
|
-
|
52
|
-
# @return [Array<#call>]
|
53
|
-
attr_reader :callbacks
|
54
|
-
|
55
|
-
|
56
|
-
def initialize(connection)
|
57
|
-
@connection = connection
|
58
|
-
# Be careful with default values for #ruby hashes: h = Hash.new(Array.new); h[:key] ||= 1
|
59
|
-
# won't assign anything to :key. MK.
|
60
|
-
@callbacks = Hash.new
|
61
|
-
end # initialize
|
62
|
-
end # Entity
|
7
|
+
# backwards compatibility
|
8
|
+
# @private
|
9
|
+
RegisterEntityMixin = Async::RegisterEntityMixin
|
10
|
+
ProtocolMethodHandlers = Async::ProtocolMethodHandlers
|
11
|
+
Entity = Async::Entity
|
63
12
|
end # Client
|
64
13
|
end # AMQ
|
data/lib/amq/client/exchange.rb
CHANGED
@@ -1,155 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require "amq/client/
|
4
|
-
require "amq/client/server_named_entity"
|
3
|
+
require "amq/client/async/exchange"
|
5
4
|
|
6
5
|
module AMQ
|
7
6
|
module Client
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
include Entity
|
12
|
-
include ServerNamedEntity
|
13
|
-
extend ProtocolMethodHandlers
|
14
|
-
|
15
|
-
TYPES = [:fanout, :direct, :topic, :headers].freeze
|
16
|
-
|
17
|
-
class IncompatibleExchangeTypeError < StandardError
|
18
|
-
def initialize(types, given)
|
19
|
-
super("#{given.inspect} exchange type is unknown. Standard types are #{TYPES.inspect}, custom exchange types must begin with x-, for example: x-recent-history")
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
# API
|
26
|
-
#
|
27
|
-
|
28
|
-
# Channel this exchange belongs to.
|
29
|
-
attr_reader :channel
|
30
|
-
|
31
|
-
# Exchange name. May be server-generated or assigned directly.
|
32
|
-
attr_reader :name
|
33
|
-
|
34
|
-
# @return [Symbol] One of :direct, :fanout, :topic, :headers
|
35
|
-
attr_reader :type
|
36
|
-
|
37
|
-
def initialize(connection, channel, name, type = :fanout)
|
38
|
-
if !(TYPES.include?(type.to_sym) || type.to_s =~ /^x-.+/i)
|
39
|
-
raise IncompatibleExchangeTypeError.new(TYPES, type)
|
40
|
-
end
|
41
|
-
|
42
|
-
@connection = connection
|
43
|
-
@channel = channel
|
44
|
-
@name = name
|
45
|
-
@type = type
|
46
|
-
|
47
|
-
# register pre-declared exchanges
|
48
|
-
if @name == AMQ::Protocol::EMPTY_STRING || @name =~ /^amq\.(fanout|topic)/
|
49
|
-
@channel.register_exchange(self)
|
50
|
-
end
|
51
|
-
|
52
|
-
super(connection)
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
def fanout?
|
57
|
-
@type == :fanout
|
58
|
-
end
|
59
|
-
|
60
|
-
def direct?
|
61
|
-
@type == :direct
|
62
|
-
end
|
63
|
-
|
64
|
-
def topic?
|
65
|
-
@type == :topic
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
def declare(passive = false, durable = false, auto_delete = false, nowait = false, arguments = nil, &block)
|
71
|
-
@connection.send_frame(Protocol::Exchange::Declare.encode(@channel.id, @name, @type.to_s, passive, durable, auto_delete, false, nowait, arguments))
|
72
|
-
|
73
|
-
unless nowait
|
74
|
-
self.define_callback(:declare, &block)
|
75
|
-
@channel.exchanges_awaiting_declare_ok.push(self)
|
76
|
-
end
|
77
|
-
|
78
|
-
self
|
79
|
-
end
|
80
|
-
|
81
|
-
|
82
|
-
def delete(if_unused = false, nowait = false, &block)
|
83
|
-
@connection.send_frame(Protocol::Exchange::Delete.encode(@channel.id, @name, if_unused, nowait))
|
84
|
-
|
85
|
-
unless nowait
|
86
|
-
self.define_callback(:delete, &block)
|
87
|
-
|
88
|
-
# TODO: delete itself from exchanges cache
|
89
|
-
@channel.exchanges_awaiting_delete_ok.push(self)
|
90
|
-
end
|
91
|
-
|
92
|
-
self
|
93
|
-
end # delete(if_unused = false, nowait = false)
|
94
|
-
|
95
|
-
|
96
|
-
def publish(payload, routing_key = AMQ::Protocol::EMPTY_STRING, user_headers = {}, mandatory = false, immediate = false, frame_size = nil)
|
97
|
-
headers = { :priority => 0, :delivery_mode => 2, :content_type => "application/octet-stream" }.merge(user_headers)
|
98
|
-
@connection.send_frameset(Protocol::Basic::Publish.encode(@channel.id, payload, headers, @name, routing_key, mandatory, immediate, (frame_size || @connection.frame_max)))
|
99
|
-
|
100
|
-
self
|
101
|
-
end
|
102
|
-
|
103
|
-
|
104
|
-
def on_return(&block)
|
105
|
-
self.redefine_callback(:return, &block)
|
106
|
-
|
107
|
-
self
|
108
|
-
end # on_return(&block)
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
def handle_declare_ok(method)
|
114
|
-
@name = method.exchange if self.anonymous?
|
115
|
-
@channel.register_exchange(self)
|
116
|
-
|
117
|
-
self.exec_callback_once_yielding_self(:declare, method)
|
118
|
-
end
|
119
|
-
|
120
|
-
def handle_delete_ok(method)
|
121
|
-
self.exec_callback_once(:delete, method)
|
122
|
-
end # handle_delete_ok(method)
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
self.handle(Protocol::Exchange::DeclareOk) do |connection, frame|
|
127
|
-
method = frame.decode_payload
|
128
|
-
channel = connection.channels[frame.channel]
|
129
|
-
exchange = channel.exchanges_awaiting_declare_ok.shift
|
130
|
-
|
131
|
-
exchange.handle_declare_ok(method)
|
132
|
-
end # handle
|
133
|
-
|
134
|
-
|
135
|
-
self.handle(Protocol::Exchange::DeleteOk) do |connection, frame|
|
136
|
-
channel = connection.channels[frame.channel]
|
137
|
-
exchange = channel.exchanges_awaiting_delete_ok.shift
|
138
|
-
exchange.handle_delete_ok(frame.decode_payload)
|
139
|
-
end # handle
|
140
|
-
|
141
|
-
|
142
|
-
self.handle(Protocol::Basic::Return) do |connection, frame, content_frames|
|
143
|
-
channel = connection.channels[frame.channel]
|
144
|
-
method = frame.decode_payload
|
145
|
-
exchange = channel.find_exchange(method.exchange)
|
146
|
-
|
147
|
-
header = content_frames.shift
|
148
|
-
body = content_frames.map { |frame| frame.payload }.join
|
149
|
-
|
150
|
-
exchange.exec_callback(:return, method, header, body)
|
151
|
-
end
|
152
|
-
|
153
|
-
end # Exchange
|
7
|
+
# backwards compatibility
|
8
|
+
# @private
|
9
|
+
Exchange = Async::Exchange
|
154
10
|
end # Client
|
155
11
|
end # AMQ
|
@@ -1,36 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require "amq/client/
|
3
|
+
require "amq/client/async/extensions/rabbitmq/basic"
|
4
4
|
|
5
5
|
# Basic.Nack
|
6
6
|
module AMQ
|
7
7
|
module Client
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
module ChannelMixin
|
12
|
-
|
13
|
-
# Overrides {AMQ::Client::Channel#reject} behavior to use basic.nack.
|
14
|
-
#
|
15
|
-
# @api public
|
16
|
-
# @see http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack
|
17
|
-
def reject(delivery_tag, requeue = true, multi = false)
|
18
|
-
if multi
|
19
|
-
@connection.send_frame(Protocol::Basic::Nack.encode(self.id, delivery_tag, multi, requeue))
|
20
|
-
else
|
21
|
-
super(delivery_tag, requeue)
|
22
|
-
end
|
23
|
-
end # reject
|
24
|
-
|
25
|
-
end # ChannelMixin
|
26
|
-
end # Basic
|
27
|
-
end # RabbitMQ
|
28
|
-
end # Extensions
|
29
|
-
|
30
|
-
class Channel
|
31
|
-
# use modules, the native Ruby way of extension of existing classes,
|
32
|
-
# instead of reckless monkey-patching. MK.
|
33
|
-
include Extensions::RabbitMQ::Basic::ChannelMixin
|
34
|
-
end
|
8
|
+
# backwards compatibility
|
9
|
+
# @private
|
10
|
+
Extensions = Async::Extensions
|
35
11
|
end # Client
|
36
12
|
end # AMQ
|
@@ -1,246 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require "amq/client/async/extensions/rabbitmq/confirm"
|
4
|
+
|
3
5
|
module AMQ
|
4
6
|
module Client
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# In case that the broker crashes, some messages can get lost.
|
9
|
-
# Thanks to this extension, broker sends Basic.Ack when the message
|
10
|
-
# is processed by the broker. In case of persistent messages, it must
|
11
|
-
# be written to disk or ack'd on all the queues it was delivered to.
|
12
|
-
# However it doesn't have to be necessarily 1:1, because the broker
|
13
|
-
# can send Basic.Ack with multi flag to acknowledge multiple messages.
|
14
|
-
#
|
15
|
-
# So it provides clients a lightweight way of keeping track of which
|
16
|
-
# messages have been processed by the broker and which would need
|
17
|
-
# re-publishing in case of broker shutdown or network failure.
|
18
|
-
#
|
19
|
-
# Transactions are solving the same problem, but they are very slow:
|
20
|
-
# confirmations are more than 100 times faster.
|
21
|
-
#
|
22
|
-
# h2. Workflow
|
23
|
-
# * Client asks broker to confirm messages on given channel (Confirm.Select).
|
24
|
-
# * Broker sends back Confirm.Select-Ok, unless we sent Confirm.Select with nowait=true.
|
25
|
-
# * After each published message, the client receives Basic.Ack from the broker.
|
26
|
-
# * If something bad happens inside the broker, it sends Basic.Nack.
|
27
|
-
#
|
28
|
-
# h2. Gotchas
|
29
|
-
# Note that we don't keep track of messages awaiting confirmation.
|
30
|
-
# It'd add a huge overhead and it's impossible to come up with one-suits-all solution.
|
31
|
-
# If you want to create such module, you'll probably want to redefine Channel#after_publish,
|
32
|
-
# so it will put messages into a queue and then handlers for Basic.Ack and Basic.Nack.
|
33
|
-
# This is the reason why we pass every argument from Exchange#publish to Channel#after_publish.
|
34
|
-
# You should not forget though, that both of these methods can have multi flag!
|
35
|
-
#
|
36
|
-
# Transactional channel cannot be put into confirm mode and a confirm
|
37
|
-
# mode channel cannot be made transactional.
|
38
|
-
#
|
39
|
-
# If the connection between the publisher and broker drops with outstanding
|
40
|
-
# confirms, it does not necessarily mean that the messages were lost, so
|
41
|
-
# republishing may result in duplicate messages.
|
42
|
-
|
43
|
-
# h2. Learn more
|
44
|
-
# @see http://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms
|
45
|
-
# @see http://www.rabbitmq.com/amqp-0-9-1-quickref.html#class.confirm
|
46
|
-
# @see http://www.rabbitmq.com/amqp-0-9-1-reference.html#basic.ack
|
47
|
-
module Confirm
|
48
|
-
module ChannelMixin
|
49
|
-
|
50
|
-
# Change publisher index. Publisher index is incremented
|
51
|
-
# by 1 after each Basic.Publish starting at 1. This is done
|
52
|
-
# on both client and server, hence this acknowledged messages
|
53
|
-
# can be matched via its delivery-tag.
|
54
|
-
#
|
55
|
-
# @api private
|
56
|
-
attr_writer :publisher_index
|
57
|
-
|
58
|
-
# Publisher index is an index of the last message since
|
59
|
-
# the confirmations were activated, started with 1. It's
|
60
|
-
# incremented by 1 after each Basic.Publish starting at 1.
|
61
|
-
# This is done on both client and server, hence this
|
62
|
-
# acknowledged messages can be matched via its delivery-tag.
|
63
|
-
#
|
64
|
-
# @return [Integer] Current publisher index.
|
65
|
-
# @api public
|
66
|
-
def publisher_index
|
67
|
-
@publisher_index ||= 1
|
68
|
-
end
|
69
|
-
|
70
|
-
# Resets publisher index to 0
|
71
|
-
#
|
72
|
-
# @api plugin
|
73
|
-
def reset_publisher_index!
|
74
|
-
@publisher_index = 0
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
# This method is executed after publishing of each message via {Exchage#publish}.
|
79
|
-
# Currently it just increments publisher index by 1, so messages
|
80
|
-
# can be actually matched.
|
81
|
-
#
|
82
|
-
# @api plugin
|
83
|
-
def after_publish(*args)
|
84
|
-
self.publisher_index += 1
|
85
|
-
end
|
86
|
-
|
87
|
-
# Turn on confirmations for this channel and, if given,
|
88
|
-
# register callback for Confirm.Select-Ok.
|
89
|
-
#
|
90
|
-
# @raise [RuntimeError] Occurs when confirmations are already activated.
|
91
|
-
# @raise [RuntimeError] Occurs when nowait is true and block is given.
|
92
|
-
#
|
93
|
-
# @param [Boolean] nowait Whether we expect Confirm.Select-Ok to be returned by the broker or not.
|
94
|
-
# @yield [method] Callback which will be executed once we receive Confirm.Select-Ok.
|
95
|
-
# @yieldparam [AMQ::Protocol::Confirm::SelectOk] method Protocol method class instance.
|
96
|
-
#
|
97
|
-
# @return [self] self.
|
98
|
-
#
|
99
|
-
# @see #confirm
|
100
|
-
def confirm_select(nowait = false, &block)
|
101
|
-
if nowait && block
|
102
|
-
raise "You can't use Confirm.Select with nowait=true and a callback at the same time."
|
103
|
-
end
|
104
|
-
|
105
|
-
@uses_publisher_confirmations = true
|
106
|
-
self.redefine_callback(:confirm_select, &block)
|
107
|
-
@connection.send_frame(Protocol::Confirm::Select.encode(@id, nowait))
|
108
|
-
|
109
|
-
self
|
110
|
-
end
|
111
|
-
|
112
|
-
# @return [Boolean]
|
113
|
-
def uses_publisher_confirmations?
|
114
|
-
@uses_publisher_confirmations
|
115
|
-
end # uses_publisher_confirmations?
|
116
|
-
|
117
|
-
|
118
|
-
# Turn on confirmations for this channel and, if given,
|
119
|
-
# register callback for basic.ack from the broker.
|
120
|
-
#
|
121
|
-
# @raise [RuntimeError] Occurs when confirmations are already activated.
|
122
|
-
# @raise [RuntimeError] Occurs when nowait is true and block is given.
|
123
|
-
# @param [Boolean] nowait Whether we expect Confirm.Select-Ok to be returned by the broker or not.
|
124
|
-
#
|
125
|
-
# @yield [basick_ack] Callback which will be executed every time we receive Basic.Ack from the broker.
|
126
|
-
# @yieldparam [AMQ::Protocol::Basic::Ack] basick_ack Protocol method class instance.
|
127
|
-
#
|
128
|
-
# @return [self] self.
|
129
|
-
def on_ack(nowait = false, &block)
|
130
|
-
self.use_publisher_confirmations! unless self.uses_publisher_confirmations?
|
131
|
-
|
132
|
-
self.define_callback(:ack, &block) if block
|
133
|
-
|
134
|
-
self
|
135
|
-
end
|
136
|
-
|
137
|
-
|
138
|
-
# Register error callback for Basic.Nack. It's called
|
139
|
-
# when message(s) is rejected.
|
140
|
-
#
|
141
|
-
# @return [self] self
|
142
|
-
def on_nack(&block)
|
143
|
-
self.define_callback(:nack, &block) if block
|
144
|
-
|
145
|
-
self
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
# Handler for Confirm.Select-Ok. By default, it just
|
152
|
-
# executes hook specified via the #confirmations method
|
153
|
-
# with a single argument, a protocol method class
|
154
|
-
# instance (an instance of AMQ::Protocol::Confirm::SelectOk)
|
155
|
-
# and then it deletes the callback, since Confirm.Select
|
156
|
-
# is supposed to be sent just once.
|
157
|
-
#
|
158
|
-
# @api plugin
|
159
|
-
def handle_select_ok(method)
|
160
|
-
self.exec_callback_once(:confirm_select, method)
|
161
|
-
end
|
162
|
-
|
163
|
-
# Handler for Basic.Ack. By default, it just
|
164
|
-
# executes hook specified via the #confirm method
|
165
|
-
# with a single argument, a protocol method class
|
166
|
-
# instance (an instance of AMQ::Protocol::Basic::Ack).
|
167
|
-
#
|
168
|
-
# @api plugin
|
169
|
-
def handle_basic_ack(method)
|
170
|
-
self.exec_callback(:ack, method)
|
171
|
-
end
|
172
|
-
|
173
|
-
|
174
|
-
# Handler for Basic.Nack. By default, it just
|
175
|
-
# executes hook specified via the #confirm_failed method
|
176
|
-
# with a single argument, a protocol method class
|
177
|
-
# instance (an instance of AMQ::Protocol::Basic::Nack).
|
178
|
-
#
|
179
|
-
# @api plugin
|
180
|
-
def handle_basic_nack(method)
|
181
|
-
self.exec_callback(:nack, method)
|
182
|
-
end
|
183
|
-
|
184
|
-
|
185
|
-
def reset_state!
|
186
|
-
super
|
187
|
-
|
188
|
-
@uses_publisher_confirmations = false
|
189
|
-
end
|
190
|
-
|
191
|
-
|
192
|
-
def self.included(host)
|
193
|
-
host.handle(Protocol::Confirm::SelectOk) do |connection, frame|
|
194
|
-
method = frame.decode_payload
|
195
|
-
channel = connection.channels[frame.channel]
|
196
|
-
channel.handle_select_ok(method)
|
197
|
-
end
|
198
|
-
|
199
|
-
host.handle(Protocol::Basic::Ack) do |connection, frame|
|
200
|
-
method = frame.decode_payload
|
201
|
-
channel = connection.channels[frame.channel]
|
202
|
-
channel.handle_basic_ack(method)
|
203
|
-
end
|
204
|
-
|
205
|
-
host.handle(Protocol::Basic::Nack) do |connection, frame|
|
206
|
-
method = frame.decode_payload
|
207
|
-
channel = connection.channels[frame.channel]
|
208
|
-
channel.handle_basic_nack(method)
|
209
|
-
end
|
210
|
-
end # self.included(host)
|
211
|
-
end # ChannelMixin
|
212
|
-
|
213
|
-
|
214
|
-
module ExchangeMixin
|
215
|
-
# Publish message and then run #after_publish on channel belonging
|
216
|
-
# to the exchange. This is used for incrementing the publisher index.
|
217
|
-
#
|
218
|
-
# @api public
|
219
|
-
# @see AMQ::Client::Exchange#publish
|
220
|
-
# @see AMQ::Client::Extensions::RabbitMQ::Channel#publisher_index
|
221
|
-
# @return [self] self
|
222
|
-
def publish(*args)
|
223
|
-
super(*args)
|
224
|
-
@channel.after_publish(*args)
|
225
|
-
|
226
|
-
self
|
227
|
-
end # publish
|
228
|
-
end # ExchangeMixin
|
229
|
-
end # Confirm
|
230
|
-
end # RabbitMQ
|
231
|
-
end # Extensions
|
232
|
-
|
233
|
-
|
234
|
-
class Channel
|
235
|
-
# use modules, a native Ruby way of extension of existing classes,
|
236
|
-
# instead of reckless monkey-patching. MK.
|
237
|
-
include Extensions::RabbitMQ::Confirm::ChannelMixin
|
238
|
-
end # Channel
|
239
|
-
|
240
|
-
class Exchange
|
241
|
-
# use modules, a native Ruby way of extension of existing classes,
|
242
|
-
# instead of reckless monkey-patching. MK.
|
243
|
-
include Extensions::RabbitMQ::Confirm::ExchangeMixin
|
244
|
-
end # Exchange
|
7
|
+
# backwards compatibility
|
8
|
+
# @private
|
9
|
+
Extensions = Async::Extensions
|
245
10
|
end # Client
|
246
11
|
end # AMQ
|