bunny 2.23.0 → 3.0.0
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/README.md +38 -36
- data/lib/amq/protocol/extensions.rb +2 -0
- data/lib/bunny/authentication/credentials_encoder.rb +2 -0
- data/lib/bunny/authentication/external_mechanism_encoder.rb +2 -0
- data/lib/bunny/authentication/plain_mechanism_encoder.rb +2 -0
- data/lib/bunny/channel.rb +778 -150
- data/lib/bunny/channel_id_allocator.rb +2 -0
- data/lib/bunny/concurrent/atomic_fixnum.rb +2 -0
- data/lib/bunny/concurrent/condition.rb +2 -0
- data/lib/bunny/concurrent/continuation_queue.rb +2 -0
- data/lib/bunny/concurrent/exception_accumulator.rb +115 -0
- data/lib/bunny/concurrent/synchronized_sorted_set.rb +2 -0
- data/lib/bunny/consumer.rb +4 -11
- data/lib/bunny/consumer_tag_generator.rb +2 -0
- data/lib/bunny/consumer_work_pool.rb +2 -0
- data/lib/bunny/cruby/socket.rb +36 -2
- data/lib/bunny/cruby/ssl_socket.rb +44 -1
- data/lib/bunny/delivery_info.rb +23 -15
- data/lib/bunny/exceptions.rb +33 -2
- data/lib/bunny/exchange.rb +27 -13
- data/lib/bunny/framing.rb +2 -0
- data/lib/bunny/get_response.rb +20 -14
- data/lib/bunny/heartbeat_sender.rb +4 -2
- data/lib/bunny/message_properties.rb +2 -0
- data/lib/bunny/queue.rb +31 -39
- data/lib/bunny/reader_loop.rb +9 -7
- data/lib/bunny/return_info.rb +18 -11
- data/lib/bunny/session.rb +387 -63
- data/lib/bunny/socket.rb +7 -12
- data/lib/bunny/ssl_socket.rb +7 -12
- data/lib/bunny/test_kit.rb +1 -0
- data/lib/bunny/timeout.rb +2 -0
- data/lib/bunny/timestamp.rb +3 -1
- data/lib/bunny/topology_recovery_filter.rb +71 -0
- data/lib/bunny/topology_registry.rb +824 -0
- data/lib/bunny/transport.rb +54 -49
- data/lib/bunny/version.rb +2 -1
- data/lib/bunny.rb +2 -1
- metadata +25 -14
- data/lib/bunny/concurrent/linked_continuation_queue.rb +0 -61
- data/lib/bunny/jruby/socket.rb +0 -57
- data/lib/bunny/jruby/ssl_socket.rb +0 -58
- data/lib/bunny/versioned_delivery_tag.rb +0 -28
data/lib/bunny/queue.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "bunny/get_response"
|
|
2
4
|
|
|
3
5
|
module Bunny
|
|
@@ -15,8 +17,10 @@ module Bunny
|
|
|
15
17
|
QUORUM = "quorum"
|
|
16
18
|
CLASSIC = "classic"
|
|
17
19
|
STREAM = "stream"
|
|
20
|
+
DELAYED = "delayed"
|
|
21
|
+
JMS = "jms"
|
|
18
22
|
|
|
19
|
-
KNOWN = [CLASSIC, QUORUM, STREAM]
|
|
23
|
+
KNOWN = [CLASSIC, QUORUM, STREAM, DELAYED, JMS]
|
|
20
24
|
|
|
21
25
|
def self.known?(q_type)
|
|
22
26
|
KNOWN.include?(q_type)
|
|
@@ -26,6 +30,13 @@ module Bunny
|
|
|
26
30
|
module XArgs
|
|
27
31
|
MAX_LENGTH = "x-max-length",
|
|
28
32
|
QUEUE_TYPE = "x-queue-type"
|
|
33
|
+
|
|
34
|
+
DELAYED_RETRY_TYPE = "x-delayed-retry-type"
|
|
35
|
+
DELAYED_RETRY_MIN = "x-delayed-retry-min"
|
|
36
|
+
DELAYED_RETRY_MAX = "x-delayed-retry-max"
|
|
37
|
+
|
|
38
|
+
SELECTOR_FIELDS = "x-selector-fields"
|
|
39
|
+
SELECTOR_FIELD_MAX_BYTES = "x-selector-field-max-bytes"
|
|
29
40
|
end
|
|
30
41
|
|
|
31
42
|
# @return [Bunny::Channel] Channel this queue uses
|
|
@@ -42,7 +53,7 @@ module Bunny
|
|
|
42
53
|
# @option opts [Boolean] :durable (false) Should this queue be durable?
|
|
43
54
|
# @option opts [Boolean] :auto_delete (false) Should this queue be automatically deleted when the last consumer disconnects?
|
|
44
55
|
# @option opts [Boolean] :exclusive (false) Should this queue be exclusive (only can be used by this connection, removed when the connection is closed)?
|
|
45
|
-
# @option opts [String] :type (nil) Type of the declared queue (classic, quorum or
|
|
56
|
+
# @option opts [String] :type (nil) Type of the declared queue (classic, quorum, stream, delayed, or jms)
|
|
46
57
|
# @option opts [Hash] :arguments (nil) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
|
47
58
|
#
|
|
48
59
|
# @see Bunny::Channel#queue
|
|
@@ -78,7 +89,10 @@ module Bunny
|
|
|
78
89
|
|
|
79
90
|
declare! unless opts[:no_declare]
|
|
80
91
|
|
|
92
|
+
# for basic.deliver dispatch and such
|
|
81
93
|
@channel.register_queue(self)
|
|
94
|
+
# for topology recovery
|
|
95
|
+
@channel.record_queue(self)
|
|
82
96
|
end
|
|
83
97
|
|
|
84
98
|
# @return [Boolean] true if this queue was declared as durable (will survive broker restart).
|
|
@@ -115,6 +129,13 @@ module Bunny
|
|
|
115
129
|
@arguments
|
|
116
130
|
end
|
|
117
131
|
|
|
132
|
+
# @param value [String]
|
|
133
|
+
# @private
|
|
134
|
+
def update_name_to(value)
|
|
135
|
+
@name = value
|
|
136
|
+
self
|
|
137
|
+
end
|
|
138
|
+
|
|
118
139
|
def to_s
|
|
119
140
|
oid = ("0x%x" % (self.object_id << 1))
|
|
120
141
|
"<#{self.class.name}:#{oid} @name=\"#{name}\" channel=#{@channel.to_s} @durable=#{@durable} @auto_delete=#{@auto_delete} @exclusive=#{@exclusive} @arguments=#{@arguments}>"
|
|
@@ -318,6 +339,7 @@ module Bunny
|
|
|
318
339
|
# @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
|
|
319
340
|
# @api public
|
|
320
341
|
def delete(opts = {})
|
|
342
|
+
@channel.delete_recorded_queue_named(self.name)
|
|
321
343
|
@channel.deregister_queue(self)
|
|
322
344
|
@channel.queue_delete(@name, opts)
|
|
323
345
|
end
|
|
@@ -352,42 +374,14 @@ module Bunny
|
|
|
352
374
|
s[:consumer_count]
|
|
353
375
|
end
|
|
354
376
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if self.server_named?
|
|
362
|
-
old_name = @name.dup
|
|
363
|
-
@name = AMQ::Protocol::EMPTY_STRING
|
|
364
|
-
|
|
365
|
-
@channel.deregister_queue_named(old_name)
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
# TODO: inject and use logger
|
|
369
|
-
# puts "Recovering queue #{@name}"
|
|
370
|
-
begin
|
|
371
|
-
declare! unless @options[:no_declare]
|
|
372
|
-
|
|
373
|
-
@channel.register_queue(self)
|
|
374
|
-
rescue Exception => e
|
|
375
|
-
# TODO: inject and use logger
|
|
376
|
-
puts "Caught #{e.inspect} while redeclaring and registering #{@name}!"
|
|
377
|
-
end
|
|
378
|
-
recover_bindings
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
# @private
|
|
382
|
-
def recover_bindings
|
|
383
|
-
@bindings.each do |b|
|
|
384
|
-
# TODO: inject and use logger
|
|
385
|
-
# puts "Recovering binding #{b.inspect}"
|
|
386
|
-
self.bind(b[:exchange], b)
|
|
387
|
-
end
|
|
377
|
+
def self.verify_type!(args0 = {})
|
|
378
|
+
# be extra defensive
|
|
379
|
+
args = args0 || {}
|
|
380
|
+
q_type = args["x-queue-type"] || args[:"x-queue-type"]
|
|
381
|
+
throw ArgumentError.new(
|
|
382
|
+
"unsupported queue type #{q_type.inspect}, supported ones: #{Types::KNOWN.join(', ')}") if (q_type and !Types.known?(q_type))
|
|
388
383
|
end
|
|
389
384
|
|
|
390
|
-
|
|
391
385
|
#
|
|
392
386
|
# Implementation
|
|
393
387
|
#
|
|
@@ -419,9 +413,7 @@ module Bunny
|
|
|
419
413
|
end
|
|
420
414
|
|
|
421
415
|
def verify_type!(args)
|
|
422
|
-
|
|
423
|
-
throw ArgumentError.new(
|
|
424
|
-
"unsupported queue type #{q_type.inspect}, supported ones: #{Types::KNOWN.join(', ')}") if (q_type and !Types.known?(q_type))
|
|
416
|
+
self.class.verify_type!(args)
|
|
425
417
|
end
|
|
426
418
|
end
|
|
427
419
|
end
|
data/lib/bunny/reader_loop.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "thread"
|
|
2
4
|
|
|
3
5
|
module Bunny
|
|
@@ -41,9 +43,13 @@ module Bunny
|
|
|
41
43
|
OpenSSL::OpenSSLError => e
|
|
42
44
|
break if terminate? || @session.closing? || @session.closed?
|
|
43
45
|
|
|
44
|
-
@
|
|
46
|
+
@mutex.synchronize do
|
|
47
|
+
@stopping = true
|
|
48
|
+
@network_is_down = true
|
|
49
|
+
end
|
|
50
|
+
|
|
45
51
|
if @session.automatically_recover?
|
|
46
|
-
log_exception(e, level: :
|
|
52
|
+
log_exception(e, level: :debug)
|
|
47
53
|
@session.handle_network_failure(e)
|
|
48
54
|
else
|
|
49
55
|
log_exception(e)
|
|
@@ -60,10 +66,6 @@ module Bunny
|
|
|
60
66
|
@network_is_down = true
|
|
61
67
|
@session_error_handler.raise(Bunny::NetworkFailure.new("caught an unexpected exception in the network loop: #{e.message}", e))
|
|
62
68
|
end
|
|
63
|
-
rescue Errno::EBADF => _ebadf
|
|
64
|
-
break if terminate?
|
|
65
|
-
# ignored, happens when we loop after the transport has already been closed
|
|
66
|
-
@mutex.synchronize { @stopping = true }
|
|
67
69
|
end
|
|
68
70
|
end
|
|
69
71
|
|
|
@@ -76,7 +78,7 @@ module Bunny
|
|
|
76
78
|
|
|
77
79
|
if !frame.final? || frame.method_class.has_content?
|
|
78
80
|
header = @transport.read_next_frame
|
|
79
|
-
content = ''
|
|
81
|
+
content = +''
|
|
80
82
|
|
|
81
83
|
if header.body_size > 0
|
|
82
84
|
loop do
|
data/lib/bunny/return_info.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Bunny
|
|
2
4
|
# Wraps AMQ::Protocol::Basic::Return to
|
|
3
|
-
# provide access to the
|
|
4
|
-
# well as methods.
|
|
5
|
+
# provide access to the return properties as immutable hash as
|
|
6
|
+
# well as methods. Hash representation is created lazily.
|
|
5
7
|
class ReturnInfo
|
|
6
8
|
|
|
7
9
|
#
|
|
@@ -16,29 +18,34 @@ module Bunny
|
|
|
16
18
|
|
|
17
19
|
def initialize(basic_return)
|
|
18
20
|
@basic_return = basic_return
|
|
19
|
-
@hash = {
|
|
20
|
-
:reply_code => basic_return.reply_code,
|
|
21
|
-
:reply_text => basic_return.reply_text,
|
|
22
|
-
:exchange => basic_return.exchange,
|
|
23
|
-
:routing_key => basic_return.routing_key
|
|
24
|
-
}
|
|
25
21
|
end
|
|
26
22
|
|
|
27
23
|
# Iterates over the returned delivery properties
|
|
28
24
|
# @see Enumerable#each
|
|
29
25
|
def each(*args, &block)
|
|
30
|
-
|
|
26
|
+
to_hash.each(*args, &block)
|
|
31
27
|
end
|
|
32
28
|
|
|
33
29
|
# Accesses returned delivery properties by key
|
|
34
30
|
# @see Hash#[]
|
|
35
31
|
def [](k)
|
|
36
|
-
|
|
32
|
+
case k
|
|
33
|
+
when :reply_code then @basic_return.reply_code
|
|
34
|
+
when :reply_text then @basic_return.reply_text
|
|
35
|
+
when :exchange then @basic_return.exchange
|
|
36
|
+
when :routing_key then @basic_return.routing_key
|
|
37
|
+
else nil
|
|
38
|
+
end
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
# @return [Hash] Hash representation of this returned delivery info
|
|
40
42
|
def to_hash
|
|
41
|
-
@hash
|
|
43
|
+
@hash ||= {
|
|
44
|
+
:reply_code => @basic_return.reply_code,
|
|
45
|
+
:reply_text => @basic_return.reply_text,
|
|
46
|
+
:exchange => @basic_return.exchange,
|
|
47
|
+
:routing_key => @basic_return.routing_key
|
|
48
|
+
}
|
|
42
49
|
end
|
|
43
50
|
|
|
44
51
|
# @private
|