march_hare 2.0.0-java
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 +7 -0
- data/lib/ext/commons-io.jar +0 -0
- data/lib/ext/rabbitmq-client.jar +0 -0
- data/lib/hot_bunnies.rb +2 -0
- data/lib/march_hare.rb +33 -0
- data/lib/march_hare/channel.rb +952 -0
- data/lib/march_hare/consumers.rb +2 -0
- data/lib/march_hare/consumers/base.rb +121 -0
- data/lib/march_hare/consumers/blocking.rb +73 -0
- data/lib/march_hare/exceptions.rb +174 -0
- data/lib/march_hare/exchange.rb +179 -0
- data/lib/march_hare/juc.rb +9 -0
- data/lib/march_hare/metadata.rb +93 -0
- data/lib/march_hare/queue.rb +265 -0
- data/lib/march_hare/session.rb +440 -0
- data/lib/march_hare/shutdown_listener.rb +15 -0
- data/lib/march_hare/thread_pools.rb +32 -0
- data/lib/march_hare/version.rb +5 -0
- data/lib/march_hare/versioned_delivery_tag.rb +28 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: be4969a5a66b26f56f7b8bc7eefcd1f4e1627a5c
|
4
|
+
data.tar.gz: 5fde2978b7a8a1fd08b11734a046eb2200839635
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ca66334d7d382f363a5ac1cf2f77e619e99125e48b616819f6b3e5a1dd48df4571c55e6e838e88fa6488a1dcd619eeec800f5953f96602487e86050503888f81
|
7
|
+
data.tar.gz: a4ef1bd5756dac9a0ee79a9d619c4b57a2e0b19e0332ea3383335b4974780d93c11ff80fabfa9af9f41f6feb2c44fecff56e6904291ba0004330357c7c44c57e
|
Binary file
|
Binary file
|
data/lib/hot_bunnies.rb
ADDED
data/lib/march_hare.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'java'
|
4
|
+
require 'ext/commons-io'
|
5
|
+
require 'ext/rabbitmq-client'
|
6
|
+
|
7
|
+
require 'march_hare/version'
|
8
|
+
require 'march_hare/exceptions'
|
9
|
+
require 'march_hare/session'
|
10
|
+
|
11
|
+
# MarchHare is a JRuby client for RabbitMQ built on top of the official Java client.
|
12
|
+
#
|
13
|
+
# @see MarchHare.connect
|
14
|
+
# @see MarchHare::Session
|
15
|
+
# @see MarchHare::Channel
|
16
|
+
module MarchHare
|
17
|
+
# Delegates to {MarchHare::Session.connect}
|
18
|
+
# @see MarchHare::Session.connect
|
19
|
+
def self.connect(*args)
|
20
|
+
Session.connect(*args)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Backwards compatibility
|
25
|
+
# @private
|
26
|
+
Hotbunnies = MarchHare
|
27
|
+
# Backwards compatibility
|
28
|
+
# @private
|
29
|
+
HotBunnies = MarchHare
|
30
|
+
|
31
|
+
require 'march_hare/channel'
|
32
|
+
require 'march_hare/queue'
|
33
|
+
require 'march_hare/exchange'
|
@@ -0,0 +1,952 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "march_hare/shutdown_listener"
|
3
|
+
require "march_hare/juc"
|
4
|
+
|
5
|
+
module MarchHare
|
6
|
+
# ## Channels in RabbitMQ
|
7
|
+
#
|
8
|
+
# To quote {http://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf AMQP 0.9.1 specification}:
|
9
|
+
#
|
10
|
+
# AMQP 0.9.1 is a multi-channelled protocol. Channels provide a way to multiplex
|
11
|
+
# a heavyweight TCP/IP connection into several light weight connections.
|
12
|
+
# This makes the protocol more “firewall friendly” since port usage is predictable.
|
13
|
+
# It also means that traffic shaping and other network QoS features can be easily employed.
|
14
|
+
# Channels are independent of each other and can perform different functions simultaneously
|
15
|
+
# with other channels, the available bandwidth being shared between the concurrent activities.
|
16
|
+
#
|
17
|
+
#
|
18
|
+
# ## Opening Channels
|
19
|
+
#
|
20
|
+
# Channels can be opened either via `MarchHare::Session#create_channel` (sufficient in the majority
|
21
|
+
# of cases) or by instantiating `MarchHare::Channel` directly:
|
22
|
+
#
|
23
|
+
# @example Using {MarchHare::Session#create_channel}:
|
24
|
+
# conn = MarchHare.new
|
25
|
+
# conn.start
|
26
|
+
#
|
27
|
+
# ch = conn.create_channel
|
28
|
+
#
|
29
|
+
# This will automatically allocate a channel id.
|
30
|
+
#
|
31
|
+
# ## Closing Channels
|
32
|
+
#
|
33
|
+
# Channels are closed via {MarchHare::Channel#close}. Channels that get a channel-level exception are
|
34
|
+
# closed, too. Closed channels can no longer be used. Attempts to use them will raise
|
35
|
+
# {MarchHare::ChannelAlreadyClosed}.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
#
|
39
|
+
# ch = conn.create_channel
|
40
|
+
# ch.close
|
41
|
+
#
|
42
|
+
# ## Higher-level API
|
43
|
+
#
|
44
|
+
# MarchHare offers two sets of methods on {MarchHare::Channel}: known as higher-level and lower-level
|
45
|
+
# APIs, respectively. Higher-level API mimics {http://rubyamqp.info amqp gem} API where
|
46
|
+
# exchanges and queues are objects (instance of {MarchHare::Exchange} and {MarchHare::Queue}, respectively).
|
47
|
+
# Lower-level API is built around AMQP 0.9.1 methods (commands), where queues and exchanges are
|
48
|
+
# passed as strings (à la RabbitMQ Java client, {http://clojurerabbitmq.info Langohr} and Pika).
|
49
|
+
#
|
50
|
+
# ### Queue Operations In Higher-level API
|
51
|
+
#
|
52
|
+
# * {MarchHare::Channel#queue} is used to declare queues. The rest of the API is in {MarchHare::Queue}.
|
53
|
+
#
|
54
|
+
#
|
55
|
+
# ### Exchange Operations In Higher-level API
|
56
|
+
#
|
57
|
+
# * {MarchHare::Channel#topic} declares a topic exchange. The rest of the API is in {MarchHare::Exchange}.
|
58
|
+
# * {MarchHare::Channel#direct} declares a direct exchange.
|
59
|
+
# * {MarchHare::Channel#fanout} declares a fanout exchange.
|
60
|
+
# * {MarchHare::Channel#headers} declares a headers exchange.
|
61
|
+
# * {MarchHare::Channel#default_exchange}
|
62
|
+
# * {MarchHare::Channel#exchange} is used to declare exchanges with type specified as a symbol or string.
|
63
|
+
#
|
64
|
+
#
|
65
|
+
# ## Channel Qos (Prefetch Level)
|
66
|
+
#
|
67
|
+
# It is possible to control how many messages at most a consumer will be given (before it acknowledges
|
68
|
+
# or rejects previously consumed ones). This setting is per channel and controlled via {MarchHare::Channel#prefetch}.
|
69
|
+
#
|
70
|
+
#
|
71
|
+
# ## Channel IDs
|
72
|
+
#
|
73
|
+
# Channels are identified by their ids which are integers. MarchHare takes care of allocating and
|
74
|
+
# releasing them as channels are opened and closed. It is almost never necessary to specify
|
75
|
+
# channel ids explicitly.
|
76
|
+
#
|
77
|
+
# There is a limit on the maximum number of channels per connection, usually 65536. Note
|
78
|
+
# that allocating channels is very cheap on both client and server so having tens, hundreds
|
79
|
+
# or even thousands of channels is possible.
|
80
|
+
#
|
81
|
+
# ## Channels and Error Handling
|
82
|
+
#
|
83
|
+
# Channel-level exceptions are more common than connection-level ones and often indicate
|
84
|
+
# issues applications can recover from (such as consuming from or trying to delete
|
85
|
+
# a queue that does not exist).
|
86
|
+
#
|
87
|
+
# With MarchHare, channel-level exceptions are raised as Ruby exceptions, for example,
|
88
|
+
# {MarchHare::NotFound}, that provide access to the underlying `channel.close` method
|
89
|
+
# information.
|
90
|
+
#
|
91
|
+
# @example Handling 404 NOT_FOUND
|
92
|
+
# begin
|
93
|
+
# ch.queue_delete("queue_that_should_not_exist#{rand}")
|
94
|
+
# rescue MarchHare::NotFound => e
|
95
|
+
# puts "Channel-level exception! Code: #{e.channel_close.reply_code}, message: #{e.channel_close.reply_text}"
|
96
|
+
# end
|
97
|
+
#
|
98
|
+
# @example Handling 406 PRECONDITION_FAILED
|
99
|
+
# begin
|
100
|
+
# ch2 = conn.create_channel
|
101
|
+
# q = "rubymarchhare.examples.recovery.q#{rand}"
|
102
|
+
#
|
103
|
+
# ch2.queue_declare(q, :durable => false)
|
104
|
+
# ch2.queue_declare(q, :durable => true)
|
105
|
+
# rescue MarchHare::PreconditionFailed => e
|
106
|
+
# puts "Channel-level exception! Code: #{e.channel_close.reply_code}, message: #{e.channel_close.reply_text}"
|
107
|
+
# ensure
|
108
|
+
# conn.create_channel.queue_delete(q)
|
109
|
+
# end
|
110
|
+
#
|
111
|
+
# @see MarchHare::Session#create_channel
|
112
|
+
# @see http://www.rabbitmq.com/tutorials/amqp-concepts.html AMQP 0.9.1 Model Concepts Guide
|
113
|
+
# @see http://rubymarchhare.info/articles/getting_started.html Getting Started with RabbitMQ Using MarchHare
|
114
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers
|
115
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishing
|
116
|
+
class Channel
|
117
|
+
# @return [Array<MarchHare::Consumer>] Consumers on this channel
|
118
|
+
attr_reader :consumers
|
119
|
+
|
120
|
+
# @private
|
121
|
+
def initialize(session, delegate)
|
122
|
+
@connection = session
|
123
|
+
@delegate = delegate
|
124
|
+
|
125
|
+
@exchanges = JavaConcurrent::ConcurrentHashMap.new
|
126
|
+
@queues = JavaConcurrent::ConcurrentHashMap.new
|
127
|
+
# we keep track of consumers in part to gracefully shut down their
|
128
|
+
# executors when the channel is closed. This frees library users
|
129
|
+
# from having to worry about this. MK.
|
130
|
+
@consumers = JavaConcurrent::ConcurrentHashMap.new
|
131
|
+
@shutdown_hooks = Array.new
|
132
|
+
@recoveries_counter = JavaConcurrent::AtomicInteger.new(0)
|
133
|
+
|
134
|
+
on_shutdown do |ch, cause|
|
135
|
+
ch.gracefully_shut_down_consumers
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# @return [MarchHare::Session] Connection this channel is on
|
140
|
+
def session
|
141
|
+
@connection
|
142
|
+
end
|
143
|
+
alias client session
|
144
|
+
alias connection session
|
145
|
+
|
146
|
+
# @return [Integer] Channel id
|
147
|
+
def channel_number
|
148
|
+
@delegate.channel_number
|
149
|
+
end
|
150
|
+
alias id channel_number
|
151
|
+
alias number channel_number
|
152
|
+
|
153
|
+
# Closes the channel.
|
154
|
+
#
|
155
|
+
# Closed channels can no longer be used. Closed channel id is
|
156
|
+
# returned back to the pool of available ids and may be used by
|
157
|
+
# a different channel opened later.
|
158
|
+
def close(code = 200, reason = "Goodbye")
|
159
|
+
v = @delegate.close(code, reason)
|
160
|
+
|
161
|
+
@consumers.each do |tag, consumer|
|
162
|
+
consumer.gracefully_shut_down
|
163
|
+
end
|
164
|
+
|
165
|
+
@connection.unregister_channel(self)
|
166
|
+
|
167
|
+
v
|
168
|
+
end
|
169
|
+
|
170
|
+
# Defines a shutdown event callback. Shutdown events are
|
171
|
+
# broadcasted when a channel is closed, either explicitly
|
172
|
+
# or forcefully, or due to a network/peer failure.
|
173
|
+
def on_shutdown(&block)
|
174
|
+
sh = ShutdownListener.new(self, &block)
|
175
|
+
|
176
|
+
@shutdown_hooks << sh
|
177
|
+
@delegate.add_shutdown_listener(sh)
|
178
|
+
|
179
|
+
sh
|
180
|
+
end
|
181
|
+
|
182
|
+
# @private
|
183
|
+
def automatically_recover(session, java_connection)
|
184
|
+
jch = java_connection.create_channel(id)
|
185
|
+
|
186
|
+
self.revive_with(jch)
|
187
|
+
self.recover_shutdown_hooks
|
188
|
+
|
189
|
+
self.recover_prefetch_setting
|
190
|
+
self.recover_exchanges
|
191
|
+
# # this includes bindings recovery
|
192
|
+
self.recover_queues
|
193
|
+
self.recover_consumers
|
194
|
+
self.increment_recoveries_counter
|
195
|
+
end
|
196
|
+
|
197
|
+
# @private
|
198
|
+
def revive_with(java_ch)
|
199
|
+
@delegate = java_ch
|
200
|
+
end
|
201
|
+
|
202
|
+
# @private
|
203
|
+
def recover_shutdown_hooks
|
204
|
+
@shutdown_hooks.each do |sh|
|
205
|
+
@delegate.add_shutdown_listener(sh)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# Recovers basic.qos setting. Used by the Automatic Network Failure
|
210
|
+
# Recovery feature.
|
211
|
+
#
|
212
|
+
def recover_prefetch_setting
|
213
|
+
basic_qos(@prefetch_count) if @prefetch_count
|
214
|
+
end
|
215
|
+
|
216
|
+
# Recovers exchanges. Used by the Automatic Network Failure
|
217
|
+
# Recovery feature.
|
218
|
+
#
|
219
|
+
def recover_exchanges
|
220
|
+
@exchanges.values.each do |x|
|
221
|
+
begin
|
222
|
+
x.recover_from_network_failure
|
223
|
+
rescue Exception => e
|
224
|
+
# TODO: logger
|
225
|
+
$stderr.puts "Caught exception when recovering exchange #{x.name}"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Recovers queues and bindings. Used by the Automatic Network Failure
|
231
|
+
# Recovery feature.
|
232
|
+
def recover_queues
|
233
|
+
@queues.values.each do |q|
|
234
|
+
begin
|
235
|
+
q.recover_from_network_failure
|
236
|
+
rescue Exception => e
|
237
|
+
# TODO: logger
|
238
|
+
$stderr.puts "Caught exception when recovering queue #{q.name}"
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
# Recovers consumers. Used by the Automatic Network Failure
|
244
|
+
# Recovery feature.
|
245
|
+
def recover_consumers
|
246
|
+
@consumers.values.each do |c|
|
247
|
+
begin
|
248
|
+
self.unregister_consumer(c)
|
249
|
+
c.recover_from_network_failure
|
250
|
+
rescue Exception => e
|
251
|
+
# TODO: logger
|
252
|
+
$stderr.puts "Caught exception when recovering consumer #{c.consumer_tag}"
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# @private
|
258
|
+
def increment_recoveries_counter
|
259
|
+
@recoveries_counter.increment_and_get
|
260
|
+
end
|
261
|
+
|
262
|
+
attr_reader :recoveries_counter
|
263
|
+
|
264
|
+
# @group Exchanges
|
265
|
+
|
266
|
+
# Declares a headers exchange or looks it up in the cache of previously
|
267
|
+
# declared exchanges.
|
268
|
+
#
|
269
|
+
# @param [String] name Exchange name
|
270
|
+
# @param [Hash] opts Exchange parameters
|
271
|
+
#
|
272
|
+
# @option options [String,Symbol] :type (:direct) Exchange type, e.g. :fanout or "x-consistent-hash"
|
273
|
+
# @option options [Boolean] :durable (false) Should the exchange be durable?
|
274
|
+
# @option options [Boolean] :auto_delete (false) Should the exchange be automatically deleted when no longer in use?
|
275
|
+
# @option options [Hash] :arguments ({}) Optional exchange arguments
|
276
|
+
#
|
277
|
+
# @return [MarchHare::Exchange] Exchange instance
|
278
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishing guide
|
279
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
280
|
+
def exchange(name, options={})
|
281
|
+
dx = Exchange.new(self, name, options).tap do |x|
|
282
|
+
x.declare!
|
283
|
+
end
|
284
|
+
|
285
|
+
self.register_exchange(dx)
|
286
|
+
end
|
287
|
+
|
288
|
+
# Declares a fanout exchange or looks it up in the cache of previously
|
289
|
+
# declared exchanges.
|
290
|
+
#
|
291
|
+
# @param [String] name Exchange name
|
292
|
+
# @param [Hash] opts Exchange parameters
|
293
|
+
#
|
294
|
+
# @option opts [Boolean] :durable (false) Should the exchange be durable?
|
295
|
+
# @option opts [Boolean] :auto_delete (false) Should the exchange be automatically deleted when no longer in use?
|
296
|
+
# @option opts [Hash] :arguments ({}) Optional exchange arguments (used by RabbitMQ extensions)
|
297
|
+
#
|
298
|
+
# @return [MarchHare::Exchange] Exchange instance
|
299
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishing guide
|
300
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
301
|
+
def fanout(name, opts = {})
|
302
|
+
dx = Exchange.new(self, name, opts.merge(:type => "fanout")).tap do |x|
|
303
|
+
x.declare!
|
304
|
+
end
|
305
|
+
|
306
|
+
self.register_exchange(dx)
|
307
|
+
end
|
308
|
+
|
309
|
+
# Declares a direct exchange or looks it up in the cache of previously
|
310
|
+
# declared exchanges.
|
311
|
+
#
|
312
|
+
# @param [String] name Exchange name
|
313
|
+
# @param [Hash] opts Exchange parameters
|
314
|
+
#
|
315
|
+
# @option opts [Boolean] :durable (false) Should the exchange be durable?
|
316
|
+
# @option opts [Boolean] :auto_delete (false) Should the exchange be automatically deleted when no longer in use?
|
317
|
+
# @option opts [Hash] :arguments ({}) Optional exchange arguments (used by RabbitMQ extensions)
|
318
|
+
#
|
319
|
+
# @return [MarchHare::Exchange] Exchange instance
|
320
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishing guide
|
321
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
322
|
+
def direct(name, opts = {})
|
323
|
+
dx = Exchange.new(self, name, opts.merge(:type => "direct")).tap do |x|
|
324
|
+
x.declare!
|
325
|
+
end
|
326
|
+
|
327
|
+
self.register_exchange(dx)
|
328
|
+
end
|
329
|
+
|
330
|
+
# Declares a topic exchange or looks it up in the cache of previously
|
331
|
+
# declared exchanges.
|
332
|
+
#
|
333
|
+
# @param [String] name Exchange name
|
334
|
+
# @param [Hash] opts Exchange parameters
|
335
|
+
#
|
336
|
+
# @option opts [Boolean] :durable (false) Should the exchange be durable?
|
337
|
+
# @option opts [Boolean] :auto_delete (false) Should the exchange be automatically deleted when no longer in use?
|
338
|
+
# @option opts [Hash] :arguments ({}) Optional exchange arguments (used by RabbitMQ extensions)
|
339
|
+
#
|
340
|
+
# @return [MarchHare::Exchange] Exchange instance
|
341
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishing guide
|
342
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
343
|
+
def topic(name, opts = {})
|
344
|
+
dx = Exchange.new(self, name, opts.merge(:type => "topic")).tap do |x|
|
345
|
+
x.declare!
|
346
|
+
end
|
347
|
+
|
348
|
+
self.register_exchange(dx)
|
349
|
+
end
|
350
|
+
|
351
|
+
# Declares a headers exchange or looks it up in the cache of previously
|
352
|
+
# declared exchanges.
|
353
|
+
#
|
354
|
+
# @param [String] name Exchange name
|
355
|
+
# @param [Hash] opts Exchange parameters
|
356
|
+
#
|
357
|
+
# @option opts [Boolean] :durable (false) Should the exchange be durable?
|
358
|
+
# @option opts [Boolean] :auto_delete (false) Should the exchange be automatically deleted when no longer in use?
|
359
|
+
# @option opts [Hash] :arguments ({}) Optional exchange arguments
|
360
|
+
#
|
361
|
+
# @return [MarchHare::Exchange] Exchange instance
|
362
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishing guide
|
363
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
364
|
+
def headers(name, opts = {})
|
365
|
+
dx = Exchange.new(self, name, opts.merge(:type => "headers")).tap do |x|
|
366
|
+
x.declare!
|
367
|
+
end
|
368
|
+
|
369
|
+
self.register_exchange(dx)
|
370
|
+
end
|
371
|
+
|
372
|
+
# Provides access to the default exchange
|
373
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishing guide
|
374
|
+
def default_exchange
|
375
|
+
@default_exchange ||= self.exchange("", :durable => true, :auto_delete => false, :type => "direct")
|
376
|
+
end
|
377
|
+
|
378
|
+
# Declares a echange using echange.declare AMQP 0.9.1 method.
|
379
|
+
#
|
380
|
+
# @param [String] name Exchange name
|
381
|
+
# @param [Boolean] durable (false) Should information about this echange be persisted to disk so that it
|
382
|
+
# can survive broker restarts? Typically set to true for long-lived exchanges.
|
383
|
+
# @param [Boolean] auto_delete (false) Should this echange be deleted when it is no longer used?
|
384
|
+
# @param [Boolean] passive (false) If true, exchange will be checked for existence. If it does not
|
385
|
+
# exist, {MarchHare::NotFound} will be raised.
|
386
|
+
#
|
387
|
+
# @return RabbitMQ response
|
388
|
+
# @see http://rubymarchhare.info/articles/echanges.html Exchanges and Publishing guide
|
389
|
+
def exchange_declare(name, type, durable = false, auto_delete = false, arguments = nil)
|
390
|
+
@delegate.exchange_declare(name, type, durable, auto_delete, arguments)
|
391
|
+
end
|
392
|
+
|
393
|
+
# Binds an exchange to another exchange using exchange.bind method (RabbitMQ extension)
|
394
|
+
#
|
395
|
+
# @param [String] desitnation Destination exchange name
|
396
|
+
# @param [String] source Source exchange name
|
397
|
+
#
|
398
|
+
# @param [String] routing_key Routing key used for binding
|
399
|
+
# @param [Hash] arguments (nil) Optional arguments
|
400
|
+
#
|
401
|
+
# @return RabbitMQ response
|
402
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ extensions guide
|
403
|
+
# @see http://rubymarchhare.info/articles/bindings.html Bindings guide
|
404
|
+
def exchange_bind(destination, source, routing_key, arguments = nil)
|
405
|
+
@delegate.exchange_bind(destination, source, routing_key, arguments)
|
406
|
+
end
|
407
|
+
|
408
|
+
# Unbinds an exchange from another exchange using exchange.unbind method (RabbitMQ extension)
|
409
|
+
#
|
410
|
+
# @param [String] destination Destination exchange name
|
411
|
+
# @param [String] source Source exchange name
|
412
|
+
#
|
413
|
+
# @param [String] routing_key Routing key used for binding
|
414
|
+
# @param [Hash] arguments ({}) Optional arguments
|
415
|
+
#
|
416
|
+
# @return RabbitMQ response
|
417
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ extensions guide
|
418
|
+
# @see http://rubymarchhare.info/articles/bindings.html Bindings guide
|
419
|
+
def exchange_unbind(destination, source, routing_key, arguments = nil)
|
420
|
+
@delegate.exchange_unbind(destination, source, routing_key, arguments)
|
421
|
+
end
|
422
|
+
|
423
|
+
# @endgroup
|
424
|
+
|
425
|
+
|
426
|
+
# @group Queues
|
427
|
+
|
428
|
+
# Declares a queue or looks it up in the per-channel cache.
|
429
|
+
#
|
430
|
+
# @param [String] name Queue name. Pass an empty string to declare a server-named queue (make RabbitMQ generate a unique name).
|
431
|
+
# @param [Hash] options Queue properties and other options
|
432
|
+
#
|
433
|
+
# @option options [Boolean] :durable (false) Should this queue be durable?
|
434
|
+
# @option options [Boolean] :auto-delete (false) Should this queue be automatically deleted when the last consumer disconnects?
|
435
|
+
# @option options [Boolean] :exclusive (false) Should this queue be exclusive (only can be used by this connection, removed when the connection is closed)?
|
436
|
+
# @option options [Boolean] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
437
|
+
#
|
438
|
+
# @return [MarchHare::Queue] Queue that was declared or looked up in the cache
|
439
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
440
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ Extensions guide
|
441
|
+
def queue(name, options={})
|
442
|
+
dq = Queue.new(self, name, options).tap do |q|
|
443
|
+
q.declare!
|
444
|
+
end
|
445
|
+
|
446
|
+
self.register_queue(dq)
|
447
|
+
end
|
448
|
+
|
449
|
+
# Declares a queue using queue.declare AMQP 0.9.1 method.
|
450
|
+
#
|
451
|
+
# @param [String] name Queue name
|
452
|
+
#
|
453
|
+
# @param [Boolean] durable (false) Should information about this queue be persisted to disk so that it
|
454
|
+
# can survive broker restarts? Typically set to true for long-lived queues.
|
455
|
+
# @param [Boolean] auto_delete (false) Should this queue be deleted when the last consumer is cancelled?
|
456
|
+
# @param [Boolean] exclusive (false) Should only this connection be able to use this queue?
|
457
|
+
# If true, the queue will be automatically deleted when this
|
458
|
+
# connection is closed
|
459
|
+
# @param [Boolean] passive (false) If true, queue will be checked for existence. If it does not
|
460
|
+
# exist, {MarchHare::NotFound} will be raised.
|
461
|
+
#
|
462
|
+
# @return RabbitMQ response
|
463
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
464
|
+
def queue_declare(name, durable, exclusive, auto_delete, arguments = {})
|
465
|
+
converting_rjc_exceptions_to_ruby do
|
466
|
+
@delegate.queue_declare(name, durable, exclusive, auto_delete, arguments)
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
# Checks if a queue exists using queue.declare AMQP 0.9.1 method.
|
471
|
+
# If it does not, a channel exception will be raised.
|
472
|
+
#
|
473
|
+
# @param [String] name Queue name
|
474
|
+
#
|
475
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
476
|
+
def queue_declare_passive(name)
|
477
|
+
converting_rjc_exceptions_to_ruby do
|
478
|
+
@delegate.queue_declare_passive(name)
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
# Deletes a queue using queue.delete AMQP 0.9.1 method
|
483
|
+
#
|
484
|
+
# @param [String] name Queue name
|
485
|
+
#
|
486
|
+
# @param [Boolean] if_empty (false) Should this queue be deleted only if it has no messages?
|
487
|
+
# @param [Boolean] if_unused (false) Should this queue be deleted only if it has no consumers?
|
488
|
+
#
|
489
|
+
# @return RabbitMQ response
|
490
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
491
|
+
def queue_delete(name, if_empty = false, if_unused = false)
|
492
|
+
converting_rjc_exceptions_to_ruby do
|
493
|
+
@delegate.queue_delete(name, if_empty, if_unused)
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
# Binds a queue to an exchange using queue.bind AMQP 0.9.1 method
|
498
|
+
#
|
499
|
+
# @param [String] name Queue name
|
500
|
+
# @param [String] exchange Exchange name
|
501
|
+
#
|
502
|
+
# @param [String] routing_key Routing key used for binding
|
503
|
+
# @param [Hash] arguments (nil) Optional arguments
|
504
|
+
#
|
505
|
+
# @return RabbitMQ response
|
506
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
507
|
+
# @see http://rubymarchhare.info/articles/bindings.html Bindings guide
|
508
|
+
def queue_bind(queue, exchange, routing_key, arguments = nil)
|
509
|
+
converting_rjc_exceptions_to_ruby do
|
510
|
+
@delegate.queue_bind(queue, exchange, routing_key, arguments)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
# Unbinds a queue from an exchange using queue.unbind AMQP 0.9.1 method
|
515
|
+
#
|
516
|
+
# @param [String] name Queue name
|
517
|
+
# @param [String] exchange Exchange name
|
518
|
+
#
|
519
|
+
# @param [String] routing_key Routing key used for binding
|
520
|
+
# @param [Hash] arguments ({}) Optional arguments
|
521
|
+
#
|
522
|
+
# @return RabbitMQ response
|
523
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
524
|
+
# @see http://rubymarchhare.info/articles/bindings.html Bindings guide
|
525
|
+
def queue_unbind(queue, exchange, routing_key, arguments = nil)
|
526
|
+
converting_rjc_exceptions_to_ruby do
|
527
|
+
@delegate.queue_unbind(queue, exchange, routing_key, arguments)
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
# Purges a queue (removes all messages from it) using queue.purge AMQP 0.9.1 method.
|
532
|
+
#
|
533
|
+
# @param [String] name Queue name
|
534
|
+
#
|
535
|
+
# @return RabbitMQ response
|
536
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
537
|
+
def queue_purge(name)
|
538
|
+
converting_rjc_exceptions_to_ruby do
|
539
|
+
@delegate.queue_purge(name)
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
# @endgroup
|
544
|
+
|
545
|
+
|
546
|
+
# @group basic.*
|
547
|
+
|
548
|
+
# Publishes a message using basic.publish AMQP 0.9.1 method.
|
549
|
+
#
|
550
|
+
# @param [String] exchange Exchange to publish to
|
551
|
+
# @param [String] routing_key Routing key
|
552
|
+
# @param [String] body Message payload. It will never be modified by MarchHare or RabbitMQ in any way.
|
553
|
+
# @option opts [Boolean] :mandatory Should the message be returned if it cannot be routed to any queue?
|
554
|
+
#
|
555
|
+
# @param [Hash] properties Message properties
|
556
|
+
#
|
557
|
+
# @option properties [Boolean] :persistent Should the message be persisted to disk?
|
558
|
+
# @option properties [Integer] :timestamp A timestamp associated with this message
|
559
|
+
# @option properties [Integer] :expiration Expiration time after which the message will be deleted
|
560
|
+
# @option properties [String] :type Message type, e.g. what type of event or command this message represents. Can be any string
|
561
|
+
# @option properties [String] :reply_to Queue name other apps should send the response to
|
562
|
+
# @option properties [String] :content_type Message content type (e.g. application/json)
|
563
|
+
# @option properties [String] :content_encoding Message content encoding (e.g. gzip)
|
564
|
+
# @option properties [String] :correlation_id Message correlated to this one, e.g. what request this message is a reply for
|
565
|
+
# @option properties [Integer] :priority Message priority, 0 to 9. Not used by RabbitMQ, only applications
|
566
|
+
# @option properties [String] :message_id Any message identifier
|
567
|
+
# @option properties [String] :user_id Optional user ID. Verified by RabbitMQ against the actual connection username
|
568
|
+
# @option properties [String] :app_id Optional application ID
|
569
|
+
#
|
570
|
+
# @return [MarchHare::Channel] Self
|
571
|
+
def basic_publish(exchange, routing_key, mandatory, properties, body)
|
572
|
+
converting_rjc_exceptions_to_ruby do
|
573
|
+
@delegate.basic_publish(exchange, routing_key, mandatory, false, BasicPropertiesBuilder.build_properties_from(properties || Hash.new), body)
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
def basic_get(queue, auto_ack)
|
578
|
+
converting_rjc_exceptions_to_ruby do
|
579
|
+
@delegate.basic_get(queue, auto_ack)
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
def basic_consume(queue, auto_ack, consumer)
|
584
|
+
consumer.auto_ack = auto_ack
|
585
|
+
tag = converting_rjc_exceptions_to_ruby do
|
586
|
+
@delegate.basic_consume(queue, auto_ack, consumer)
|
587
|
+
end
|
588
|
+
self.register_consumer(tag, consumer)
|
589
|
+
|
590
|
+
tag
|
591
|
+
end
|
592
|
+
|
593
|
+
def basic_qos(prefetch_count)
|
594
|
+
r = converting_rjc_exceptions_to_ruby do
|
595
|
+
@delegate.basic_qos(prefetch_count)
|
596
|
+
end
|
597
|
+
@prefetch_count = prefetch_count
|
598
|
+
|
599
|
+
r
|
600
|
+
end
|
601
|
+
|
602
|
+
def qos(options={})
|
603
|
+
if options.size == 1 && options[:prefetch_count]
|
604
|
+
then basic_qos(options[:prefetch_count])
|
605
|
+
else basic_qos(options.fetch(:prefetch_size, 0), options.fetch(:prefetch_count, 0), options.fetch(:global, false))
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
# Sets how many messages will be given to consumers on this channel before they
|
610
|
+
# have to acknowledge or reject one of the previously consumed messages
|
611
|
+
#
|
612
|
+
# @param [Integer] prefetch_count Prefetch (QoS setting) for this channel
|
613
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishing guide
|
614
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
615
|
+
def prefetch=(n)
|
616
|
+
basic_qos(n)
|
617
|
+
end
|
618
|
+
|
619
|
+
# Acknowledges a message. Acknowledged messages are completely removed from the queue.
|
620
|
+
#
|
621
|
+
# @param [Integer] delivery_tag Delivery tag to acknowledge
|
622
|
+
# @param [Boolean] multiple (false) Should all unacknowledged messages up to this be acknowledged as well?
|
623
|
+
# @see #nack
|
624
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
625
|
+
def ack(delivery_tag, multiple = false)
|
626
|
+
guarding_against_stale_delivery_tags(delivery_tag) do
|
627
|
+
basic_ack(delivery_tag.to_i, multiple)
|
628
|
+
end
|
629
|
+
end
|
630
|
+
alias acknowledge ack
|
631
|
+
|
632
|
+
# Rejects a message. A rejected message can be requeued or
|
633
|
+
# dropped by RabbitMQ.
|
634
|
+
#
|
635
|
+
# @param [Integer] delivery_tag Delivery tag to reject
|
636
|
+
# @param [Boolean] requeue Should this message be requeued instead of dropping it?
|
637
|
+
# @see #ack
|
638
|
+
# @see #nack
|
639
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
640
|
+
def reject(delivery_tag, requeue = false)
|
641
|
+
guarding_against_stale_delivery_tags(delivery_tag) do
|
642
|
+
basic_reject(delivery_tag.to_i, requeue)
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
# Rejects a message. A rejected message can be requeued or
|
647
|
+
# dropped by RabbitMQ. This method is similar to {MarchHare::Channel#reject} but
|
648
|
+
# supports rejecting multiple messages at once, and is usually preferred.
|
649
|
+
#
|
650
|
+
# @param [Integer] delivery_tag Delivery tag to reject
|
651
|
+
# @param [Boolean] multiple (false) Should all unacknowledged messages up to this be rejected as well?
|
652
|
+
# @param [Boolean] requeue (false) Should this message be requeued instead of dropping it?
|
653
|
+
# @see #ack
|
654
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
655
|
+
def nack(delivery_tag, multiple = false, requeue = false)
|
656
|
+
guarding_against_stale_delivery_tags(delivery_tag) do
|
657
|
+
basic_nack(delivery_tag.to_i, multiple, requeue)
|
658
|
+
end
|
659
|
+
end
|
660
|
+
|
661
|
+
# Rejects or requeues a message.
|
662
|
+
#
|
663
|
+
# @param [Integer] delivery_tag Delivery tag obtained from delivery info
|
664
|
+
# @param [Boolean] requeue Should the message be requeued?
|
665
|
+
# @return [NilClass] nil
|
666
|
+
#
|
667
|
+
# @example Requeue a message
|
668
|
+
# conn = MarchHare.new
|
669
|
+
# conn.start
|
670
|
+
#
|
671
|
+
# ch = conn.create_channel
|
672
|
+
# q.subscribe do |delivery_info, properties, payload|
|
673
|
+
# # requeue the message
|
674
|
+
# ch.basic_reject(delivery_info.delivery_tag, true)
|
675
|
+
# end
|
676
|
+
#
|
677
|
+
# @example Reject a message
|
678
|
+
# conn = MarchHare.new
|
679
|
+
# conn.start
|
680
|
+
#
|
681
|
+
# ch = conn.create_channel
|
682
|
+
# q.subscribe do |delivery_info, properties, payload|
|
683
|
+
# # requeue the message
|
684
|
+
# ch.basic_reject(delivery_info.delivery_tag, false)
|
685
|
+
# end
|
686
|
+
#
|
687
|
+
# @example Requeue a message fetched via basic.get
|
688
|
+
# conn = MarchHare.new
|
689
|
+
# conn.start
|
690
|
+
#
|
691
|
+
# ch = conn.create_channel
|
692
|
+
# # we assume the queue exists and has messages
|
693
|
+
# delivery_info, properties, payload = ch.basic_get("bunny.examples.queue3", :ack => true)
|
694
|
+
# ch.basic_reject(delivery_info.delivery_tag, true)
|
695
|
+
#
|
696
|
+
# @see #basic_nack
|
697
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
698
|
+
def basic_reject(delivery_tag, requeue)
|
699
|
+
converting_rjc_exceptions_to_ruby do
|
700
|
+
@delegate.basic_reject(delivery_tag.to_i, requeue)
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
704
|
+
# Acknowledges one or more messages (deliveries).
|
705
|
+
#
|
706
|
+
# @param [Integer] delivery_tag Delivery tag obtained from delivery info
|
707
|
+
# @param [Boolean] multiple Should all deliveries up to this one be acknowledged?
|
708
|
+
# @return [NilClass] nil
|
709
|
+
#
|
710
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
711
|
+
def basic_ack(delivery_tag, multiple)
|
712
|
+
converting_rjc_exceptions_to_ruby do
|
713
|
+
@delegate.basic_ack(delivery_tag.to_i, multiple)
|
714
|
+
end
|
715
|
+
end
|
716
|
+
|
717
|
+
# Rejects or requeues messages just like {MarchHare::Channel#basic_reject} but can do so
|
718
|
+
# with multiple messages at once.
|
719
|
+
#
|
720
|
+
# @param [Integer] delivery_tag Delivery tag obtained from delivery info
|
721
|
+
# @param [Boolean] requeue Should the message be requeued?
|
722
|
+
# @param [Boolean] multiple Should all deliveries up to this one be rejected/requeued?
|
723
|
+
# @return [NilClass] nil
|
724
|
+
#
|
725
|
+
# @see http://rubymarchhare.info/articles/queues.html Queues and Consumers guide
|
726
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ Extensions guide
|
727
|
+
def basic_nack(delivery_tag, multiple = false, requeue = false)
|
728
|
+
converting_rjc_exceptions_to_ruby do
|
729
|
+
@delegate.basic_nack(delivery_tag.to_i, multiple, requeue)
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
# Redeliver unacknowledged messages
|
734
|
+
#
|
735
|
+
# @param [Boolean] requeue Should messages be requeued?
|
736
|
+
# @return RabbitMQ response
|
737
|
+
def basic_recover(requeue = true)
|
738
|
+
converting_rjc_exceptions_to_ruby do
|
739
|
+
@delegate.basic_recover(requeue)
|
740
|
+
end
|
741
|
+
end
|
742
|
+
|
743
|
+
# Redeliver unacknowledged messages
|
744
|
+
#
|
745
|
+
# @param [Boolean] requeue Should messages be requeued?
|
746
|
+
# @return RabbitMQ response
|
747
|
+
def basic_recover_async(requeue = true)
|
748
|
+
converting_rjc_exceptions_to_ruby do
|
749
|
+
@delegate.basic_recover_async(requeue)
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
753
|
+
# @endgroup
|
754
|
+
|
755
|
+
# Enables publisher confirms on the channel.
|
756
|
+
# @return [NilClass] nil
|
757
|
+
#
|
758
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishers guide
|
759
|
+
# @see http://rubymarchhare.info/articles/extensions.html RabbitMQ Extensions guide
|
760
|
+
def confirm_select
|
761
|
+
converting_rjc_exceptions_to_ruby do
|
762
|
+
@delegate.confirm_select
|
763
|
+
end
|
764
|
+
end
|
765
|
+
|
766
|
+
# Waits until all outstanding publisher confirms arrive.
|
767
|
+
#
|
768
|
+
# Takes an optional timeout in milliseconds. Will raise
|
769
|
+
# an exception in timeout has occured.
|
770
|
+
#
|
771
|
+
# @param [Integer] timeout Timeout in milliseconds
|
772
|
+
# @return [Boolean] true if all confirms were positive,
|
773
|
+
# false if some were negative
|
774
|
+
def wait_for_confirms(timeout = nil)
|
775
|
+
if timeout
|
776
|
+
converting_rjc_exceptions_to_ruby do
|
777
|
+
@delegate.wait_for_confirms(timeout)
|
778
|
+
end
|
779
|
+
else
|
780
|
+
@delegate.wait_for_confirms
|
781
|
+
end
|
782
|
+
end
|
783
|
+
|
784
|
+
def next_publisher_seq_no
|
785
|
+
@delegate.next_publisher_seq_no
|
786
|
+
end
|
787
|
+
|
788
|
+
# Enables transactions on the channel
|
789
|
+
def tx_select
|
790
|
+
converting_rjc_exceptions_to_ruby do
|
791
|
+
@delegate.tx_select
|
792
|
+
end
|
793
|
+
end
|
794
|
+
|
795
|
+
# Commits a transaction
|
796
|
+
def tx_commit
|
797
|
+
converting_rjc_exceptions_to_ruby do
|
798
|
+
@delegate.tx_commit
|
799
|
+
end
|
800
|
+
end
|
801
|
+
|
802
|
+
# Rolls back a transaction
|
803
|
+
def tx_rollback
|
804
|
+
converting_rjc_exceptions_to_ruby do
|
805
|
+
@delegate.tx_rollback
|
806
|
+
end
|
807
|
+
end
|
808
|
+
|
809
|
+
# Enables or disables channel flow. This feature id deprecated
|
810
|
+
# in RabbitMQ.
|
811
|
+
def channel_flow(active)
|
812
|
+
converting_rjc_exceptions_to_ruby do
|
813
|
+
@delegate.channel_flow(active)
|
814
|
+
end
|
815
|
+
end
|
816
|
+
|
817
|
+
# Defines a returned message handler.
|
818
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishers guide
|
819
|
+
def on_return(&block)
|
820
|
+
self.add_return_listener(BlockReturnListener.from(block))
|
821
|
+
end
|
822
|
+
|
823
|
+
# Defines a publisher confirm handler
|
824
|
+
# @see http://rubymarchhare.info/articles/exchanges.html Exchanges and Publishers guide
|
825
|
+
def on_confirm(&block)
|
826
|
+
self.add_confirm_listener(BlockConfirmListener.from(block))
|
827
|
+
end
|
828
|
+
|
829
|
+
def method_missing(selector, *args)
|
830
|
+
@delegate.__send__(selector, *args)
|
831
|
+
end
|
832
|
+
|
833
|
+
|
834
|
+
#
|
835
|
+
# Implementation
|
836
|
+
#
|
837
|
+
|
838
|
+
# @private
|
839
|
+
class BlockConfirmListener
|
840
|
+
include com.rabbitmq.client.ConfirmListener
|
841
|
+
|
842
|
+
def self.from(block)
|
843
|
+
new(block)
|
844
|
+
end
|
845
|
+
|
846
|
+
def initialize(block)
|
847
|
+
@block = block
|
848
|
+
end
|
849
|
+
|
850
|
+
def handleAck(delivery_tag, multiple)
|
851
|
+
@block.call(:ack, delivery_tag, multiple)
|
852
|
+
end
|
853
|
+
|
854
|
+
def handleNack(delivery_tag, multiple)
|
855
|
+
@block.call(:nack, delivery_tag, multiple)
|
856
|
+
end
|
857
|
+
end
|
858
|
+
|
859
|
+
# @private
|
860
|
+
class BlockReturnListener
|
861
|
+
include com.rabbitmq.client.ReturnListener
|
862
|
+
|
863
|
+
def self.from(block)
|
864
|
+
new(block)
|
865
|
+
end
|
866
|
+
|
867
|
+
def initialize(block)
|
868
|
+
@block = block
|
869
|
+
end
|
870
|
+
|
871
|
+
def handleReturn(reply_code, reply_text, exchange, routing_key, basic_properties, payload)
|
872
|
+
# TODO: convert properties to a Ruby hash
|
873
|
+
@block.call(reply_code, reply_text, exchange, routing_key, basic_properties, String.from_java_bytes(payload))
|
874
|
+
end
|
875
|
+
end
|
876
|
+
|
877
|
+
# @private
|
878
|
+
def deregister_queue(queue)
|
879
|
+
@queues.delete(queue.name)
|
880
|
+
end
|
881
|
+
|
882
|
+
# @private
|
883
|
+
def deregister_queue_named(name)
|
884
|
+
@queues.delete(name)
|
885
|
+
end
|
886
|
+
|
887
|
+
# @private
|
888
|
+
def register_queue(queue)
|
889
|
+
@queues[queue.name] = queue
|
890
|
+
end
|
891
|
+
|
892
|
+
# @private
|
893
|
+
def find_queue(name)
|
894
|
+
@queues[name]
|
895
|
+
end
|
896
|
+
|
897
|
+
# @private
|
898
|
+
def deregister_exchange(exchange)
|
899
|
+
@exchanges.delete(exchange.name)
|
900
|
+
end
|
901
|
+
|
902
|
+
# @private
|
903
|
+
def register_exchange(exchange)
|
904
|
+
@exchanges[exchange.name] = exchange
|
905
|
+
end
|
906
|
+
|
907
|
+
# @private
|
908
|
+
def register_consumer(consumer_tag, consumer)
|
909
|
+
@consumers[consumer_tag] = consumer
|
910
|
+
end
|
911
|
+
|
912
|
+
# @private
|
913
|
+
def unregister_consumer(consumer_tag)
|
914
|
+
@consumers.delete(consumer_tag)
|
915
|
+
end
|
916
|
+
|
917
|
+
# @private
|
918
|
+
def gracefully_shut_down_consumers
|
919
|
+
@consumers.each do |tag, consumer|
|
920
|
+
consumer.gracefully_shut_down
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
924
|
+
# Executes a block, catching Java exceptions RabbitMQ Java client throws and
|
925
|
+
# transforms them to Ruby exceptions that are then re-raised.
|
926
|
+
#
|
927
|
+
# @private
|
928
|
+
def converting_rjc_exceptions_to_ruby(&block)
|
929
|
+
begin
|
930
|
+
block.call
|
931
|
+
rescue Exception, java.lang.Throwable => e
|
932
|
+
Exceptions.convert_and_reraise(e)
|
933
|
+
end
|
934
|
+
end
|
935
|
+
|
936
|
+
# @private
|
937
|
+
def guarding_against_stale_delivery_tags(tag, &block)
|
938
|
+
case tag
|
939
|
+
# if a fixnum was passed, execute unconditionally. MK.
|
940
|
+
when Fixnum then
|
941
|
+
block.call
|
942
|
+
# versioned delivery tags should be checked to avoid
|
943
|
+
# sending out stale (invalid) tags after channel was reopened
|
944
|
+
# during network failure recovery. MK.
|
945
|
+
when VersionedDeliveryTag then
|
946
|
+
if !tag.stale?(@recoveries_counter.get)
|
947
|
+
block.call
|
948
|
+
end
|
949
|
+
end
|
950
|
+
end
|
951
|
+
end
|
952
|
+
end
|