bunny 1.0.7 → 2.24.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 +5 -5
- data/README.md +92 -87
- 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 +485 -186
- data/lib/bunny/channel_id_allocator.rb +8 -4
- data/lib/bunny/concurrent/atomic_fixnum.rb +2 -0
- data/lib/bunny/concurrent/condition.rb +2 -0
- data/lib/bunny/concurrent/continuation_queue.rb +37 -13
- data/lib/bunny/concurrent/synchronized_sorted_set.rb +2 -0
- data/lib/bunny/consumer.rb +20 -13
- data/lib/bunny/consumer_tag_generator.rb +6 -2
- data/lib/bunny/consumer_work_pool.rb +37 -7
- data/lib/bunny/cruby/socket.rb +51 -22
- data/lib/bunny/cruby/ssl_socket.rb +68 -5
- data/lib/bunny/delivery_info.rb +3 -1
- data/lib/bunny/exceptions.rb +27 -4
- data/lib/bunny/exchange.rb +35 -29
- data/lib/bunny/framing.rb +2 -0
- data/lib/bunny/get_response.rb +85 -0
- data/lib/bunny/heartbeat_sender.rb +9 -6
- data/lib/bunny/message_properties.rb +2 -0
- data/lib/bunny/queue.rb +89 -41
- data/lib/bunny/reader_loop.rb +72 -28
- data/lib/bunny/return_info.rb +2 -0
- data/lib/bunny/session.rb +621 -225
- data/lib/bunny/socket.rb +7 -12
- data/lib/bunny/ssl_socket.rb +7 -12
- data/lib/bunny/test_kit.rb +15 -0
- data/lib/bunny/timeout.rb +3 -12
- data/lib/bunny/timestamp.rb +24 -0
- data/lib/bunny/transport.rb +223 -98
- data/lib/bunny/version.rb +2 -1
- data/lib/bunny/versioned_delivery_tag.rb +2 -0
- data/lib/bunny.rb +54 -8
- metadata +38 -224
- data/.gitignore +0 -22
- data/.rspec +0 -3
- data/.ruby-version +0 -1
- data/.travis.yml +0 -23
- data/.yardopts +0 -8
- data/ChangeLog.md +0 -1092
- data/Gemfile +0 -54
- data/LICENSE +0 -21
- data/benchmarks/basic_publish/with_128K_messages.rb +0 -35
- data/benchmarks/basic_publish/with_1k_messages.rb +0 -35
- data/benchmarks/basic_publish/with_4K_messages.rb +0 -35
- data/benchmarks/basic_publish/with_64K_messages.rb +0 -35
- data/benchmarks/channel_open.rb +0 -28
- data/benchmarks/mutex_and_monitor.rb +0 -42
- data/benchmarks/queue_declare.rb +0 -29
- data/benchmarks/queue_declare_and_bind.rb +0 -29
- data/benchmarks/queue_declare_bind_and_delete.rb +0 -29
- data/benchmarks/synchronized_sorted_set.rb +0 -53
- data/benchmarks/write_vs_write_nonblock.rb +0 -49
- data/bin/ci/before_build.sh +0 -31
- data/bunny.gemspec +0 -40
- data/examples/connection/authentication_failure.rb +0 -16
- data/examples/connection/automatic_recovery_with_basic_get.rb +0 -40
- data/examples/connection/automatic_recovery_with_client_named_queues.rb +0 -36
- data/examples/connection/automatic_recovery_with_multiple_consumers.rb +0 -46
- data/examples/connection/automatic_recovery_with_server_named_queues.rb +0 -35
- data/examples/connection/channel_level_exception.rb +0 -35
- data/examples/connection/disabled_automatic_recovery.rb +0 -34
- data/examples/connection/heartbeat.rb +0 -17
- data/examples/connection/manually_reconnecting_consumer.rb +0 -23
- data/examples/connection/manually_reconnecting_publisher.rb +0 -28
- data/examples/connection/unknown_host.rb +0 -16
- data/examples/guides/exchanges/direct_exchange_routing.rb +0 -36
- data/examples/guides/exchanges/fanout_exchange_routing.rb +0 -28
- data/examples/guides/exchanges/headers_exchange_routing.rb +0 -31
- data/examples/guides/exchanges/mandatory_messages.rb +0 -30
- data/examples/guides/extensions/alternate_exchange.rb +0 -28
- data/examples/guides/extensions/basic_nack.rb +0 -33
- data/examples/guides/extensions/connection_blocked.rb +0 -35
- data/examples/guides/extensions/consumer_cancellation_notification.rb +0 -39
- data/examples/guides/extensions/dead_letter_exchange.rb +0 -32
- data/examples/guides/extensions/exchange_to_exchange_bindings.rb +0 -29
- data/examples/guides/extensions/per_message_ttl.rb +0 -36
- data/examples/guides/extensions/per_queue_message_ttl.rb +0 -36
- data/examples/guides/extensions/publisher_confirms.rb +0 -28
- data/examples/guides/extensions/queue_lease.rb +0 -26
- data/examples/guides/extensions/sender_selected_distribution.rb +0 -32
- data/examples/guides/getting_started/blabbr.rb +0 -27
- data/examples/guides/getting_started/hello_world.rb +0 -20
- data/examples/guides/getting_started/weathr.rb +0 -47
- data/examples/guides/queues/one_off_consumer.rb +0 -23
- data/examples/guides/queues/redeliveries.rb +0 -79
- data/lib/bunny/compatibility.rb +0 -24
- data/lib/bunny/concurrent/linked_continuation_queue.rb +0 -61
- data/lib/bunny/jruby/socket.rb +0 -40
- data/lib/bunny/jruby/ssl_socket.rb +0 -53
- data/lib/bunny/system_timer.rb +0 -20
- data/profiling/basic_publish/with_4K_messages.rb +0 -33
- data/repl +0 -3
- data/spec/compatibility/queue_declare_spec.rb +0 -44
- data/spec/compatibility/queue_declare_with_default_channel_spec.rb +0 -33
- data/spec/higher_level_api/integration/basic_ack_spec.rb +0 -71
- data/spec/higher_level_api/integration/basic_cancel_spec.rb +0 -76
- data/spec/higher_level_api/integration/basic_consume_spec.rb +0 -225
- data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +0 -54
- data/spec/higher_level_api/integration/basic_get_spec.rb +0 -48
- data/spec/higher_level_api/integration/basic_nack_spec.rb +0 -79
- data/spec/higher_level_api/integration/basic_publish_spec.rb +0 -89
- data/spec/higher_level_api/integration/basic_qos_spec.rb +0 -29
- data/spec/higher_level_api/integration/basic_recover_spec.rb +0 -18
- data/spec/higher_level_api/integration/basic_reject_spec.rb +0 -74
- data/spec/higher_level_api/integration/basic_return_spec.rb +0 -33
- data/spec/higher_level_api/integration/channel_close_spec.rb +0 -25
- data/spec/higher_level_api/integration/channel_flow_spec.rb +0 -21
- data/spec/higher_level_api/integration/channel_open_spec.rb +0 -57
- data/spec/higher_level_api/integration/confirm_select_spec.rb +0 -19
- data/spec/higher_level_api/integration/connection_spec.rb +0 -400
- data/spec/higher_level_api/integration/connection_stop_spec.rb +0 -26
- data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +0 -50
- data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +0 -128
- data/spec/higher_level_api/integration/dead_lettering_spec.rb +0 -52
- data/spec/higher_level_api/integration/exchange_bind_spec.rb +0 -31
- data/spec/higher_level_api/integration/exchange_declare_spec.rb +0 -204
- data/spec/higher_level_api/integration/exchange_delete_spec.rb +0 -105
- data/spec/higher_level_api/integration/exchange_unbind_spec.rb +0 -40
- data/spec/higher_level_api/integration/exclusive_queue_spec.rb +0 -28
- data/spec/higher_level_api/integration/heartbeat_spec.rb +0 -31
- data/spec/higher_level_api/integration/merry_go_round_spec.rb +0 -85
- data/spec/higher_level_api/integration/message_properties_access_spec.rb +0 -95
- data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +0 -24
- data/spec/higher_level_api/integration/publisher_confirms_spec.rb +0 -77
- data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +0 -65
- data/spec/higher_level_api/integration/queue_bind_spec.rb +0 -109
- data/spec/higher_level_api/integration/queue_declare_spec.rb +0 -190
- data/spec/higher_level_api/integration/queue_delete_spec.rb +0 -41
- data/spec/higher_level_api/integration/queue_purge_spec.rb +0 -30
- data/spec/higher_level_api/integration/queue_unbind_spec.rb +0 -54
- data/spec/higher_level_api/integration/read_only_consumer_spec.rb +0 -60
- data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +0 -36
- data/spec/higher_level_api/integration/tls_connection_spec.rb +0 -127
- data/spec/higher_level_api/integration/tx_commit_spec.rb +0 -21
- data/spec/higher_level_api/integration/tx_rollback_spec.rb +0 -21
- data/spec/higher_level_api/integration/with_channel_spec.rb +0 -25
- data/spec/issues/issue100_spec.rb +0 -42
- data/spec/issues/issue141_spec.rb +0 -44
- data/spec/issues/issue78_spec.rb +0 -75
- data/spec/issues/issue83_spec.rb +0 -31
- data/spec/issues/issue97_attachment.json +0 -1
- data/spec/issues/issue97_spec.rb +0 -176
- data/spec/lower_level_api/integration/basic_cancel_spec.rb +0 -69
- data/spec/lower_level_api/integration/basic_consume_spec.rb +0 -100
- data/spec/spec_helper.rb +0 -64
- data/spec/stress/channel_open_stress_spec.rb +0 -51
- data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +0 -28
- data/spec/stress/concurrent_consumers_stress_spec.rb +0 -69
- data/spec/stress/concurrent_publishers_stress_spec.rb +0 -57
- data/spec/stress/connection_open_close_spec.rb +0 -40
- data/spec/stress/long_running_consumer_spec.rb +0 -83
- data/spec/tls/cacert.pem +0 -18
- data/spec/tls/client_cert.pem +0 -18
- data/spec/tls/client_key.pem +0 -27
- data/spec/tls/server_cert.pem +0 -18
- data/spec/tls/server_key.pem +0 -27
- data/spec/unit/bunny_spec.rb +0 -15
- data/spec/unit/concurrent/atomic_fixnum_spec.rb +0 -35
- data/spec/unit/concurrent/condition_spec.rb +0 -82
- data/spec/unit/concurrent/linked_continuation_queue_spec.rb +0 -35
- data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +0 -73
- data/spec/unit/system_timer_spec.rb +0 -10
- data/spec/unit/version_delivery_tag_spec.rb +0 -28
data/lib/bunny/exchange.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'amq/protocol'
|
2
4
|
|
3
5
|
module Bunny
|
4
6
|
# Represents AMQP 0.9.1 exchanges.
|
@@ -7,9 +9,6 @@ module Bunny
|
|
7
9
|
# @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
|
8
10
|
class Exchange
|
9
11
|
|
10
|
-
include Bunny::Compatibility
|
11
|
-
|
12
|
-
|
13
12
|
#
|
14
13
|
# API
|
15
14
|
#
|
@@ -33,12 +32,12 @@ module Bunny
|
|
33
32
|
attr_accessor :opts
|
34
33
|
|
35
34
|
|
36
|
-
# The default exchange.
|
37
|
-
#
|
38
|
-
# the following routing semantics: messages will be routed to the queue
|
39
|
-
#
|
40
|
-
# a routing key of "weather.usa.ca.sandiego" and there is a queue
|
41
|
-
#
|
35
|
+
# The default exchange. This exchange is a direct exchange that is predefined by the broker
|
36
|
+
# and that cannot be removed. Every queue is bound to this exchange by default with
|
37
|
+
# the following routing semantics: messages will be routed to the queue with the same
|
38
|
+
# name as the message's routing key. In other words, if a message is published with
|
39
|
+
# a routing key of "weather.usa.ca.sandiego" and there is a queue with this name,
|
40
|
+
# the message will be routed to the queue.
|
42
41
|
#
|
43
42
|
# @param [Bunny::Channel] channel_or_connection Channel to use. {Bunny::Session} instances
|
44
43
|
# are only supported for backwards compatibility.
|
@@ -46,23 +45,22 @@ module Bunny
|
|
46
45
|
# @example Publishing a messages to the tasks queue
|
47
46
|
# channel = Bunny::Channel.new(connection)
|
48
47
|
# tasks_queue = channel.queue("tasks")
|
49
|
-
# Bunny::Exchange.default(channel).publish("make clean", routing_key => "tasks")
|
48
|
+
# Bunny::Exchange.default(channel).publish("make clean", :routing_key => "tasks")
|
50
49
|
#
|
51
50
|
# @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
|
52
51
|
# @see http://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf AMQP 0.9.1 specification (Section 2.1.2.4)
|
53
|
-
# @note Do not confuse default exchange with amq.direct: amq.direct is a pre-defined direct
|
52
|
+
# @note Do not confuse the default exchange with amq.direct: amq.direct is a pre-defined direct
|
54
53
|
# exchange that doesn't have any special routing semantics.
|
55
54
|
# @return [Exchange] An instance that corresponds to the default exchange (of type direct).
|
56
55
|
# @api public
|
57
56
|
def self.default(channel_or_connection)
|
58
|
-
self.new(
|
57
|
+
self.new(channel_or_connection, :direct, AMQ::Protocol::EMPTY_STRING, :no_declare => true)
|
59
58
|
end
|
60
59
|
|
61
|
-
# @param [Bunny::Channel]
|
62
|
-
#
|
63
|
-
# @param [
|
64
|
-
# @param [
|
65
|
-
# @param [Hash] opts Exchange properties
|
60
|
+
# @param [Bunny::Channel] channel Channel this exchange will use.
|
61
|
+
# @param [Symbol,String] type Exchange type
|
62
|
+
# @param [String] name Exchange name
|
63
|
+
# @param [Hash] opts Exchange properties
|
66
64
|
#
|
67
65
|
# @option opts [Boolean] :durable (false) Should this exchange be durable?
|
68
66
|
# @option opts [Boolean] :auto_delete (false) Should this exchange be automatically deleted when it is no longer used?
|
@@ -75,18 +73,19 @@ module Bunny
|
|
75
73
|
# @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
|
76
74
|
# @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
|
77
75
|
# @api public
|
78
|
-
def initialize(
|
79
|
-
|
80
|
-
# we just use default channel from it. MK.
|
81
|
-
@channel = channel_from(channel_or_connection)
|
76
|
+
def initialize(channel, type, name, opts = {})
|
77
|
+
@channel = channel
|
82
78
|
@name = name
|
83
79
|
@type = type
|
84
80
|
@options = self.class.add_default_options(name, opts)
|
85
81
|
|
86
82
|
@durable = @options[:durable]
|
87
83
|
@auto_delete = @options[:auto_delete]
|
84
|
+
@internal = @options[:internal]
|
88
85
|
@arguments = @options[:arguments]
|
89
86
|
|
87
|
+
@bindings = Set.new
|
88
|
+
|
90
89
|
declare! unless opts[:no_declare] || predeclared? || (@name == AMQ::Protocol::EMPTY_STRING)
|
91
90
|
|
92
91
|
@channel.register_exchange(self)
|
@@ -104,6 +103,12 @@ module Bunny
|
|
104
103
|
@auto_delete
|
105
104
|
end # auto_delete?
|
106
105
|
|
106
|
+
# @return [Boolean] true if this exchange is internal (used solely for exchange-to-exchange
|
107
|
+
# bindings and cannot be published to by clients)
|
108
|
+
def internal?
|
109
|
+
@internal
|
110
|
+
end
|
111
|
+
|
107
112
|
# @return [Hash] Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
108
113
|
# @api public
|
109
114
|
def arguments
|
@@ -170,6 +175,7 @@ module Bunny
|
|
170
175
|
# @api public
|
171
176
|
def bind(source, opts = {})
|
172
177
|
@channel.exchange_bind(source, self, opts)
|
178
|
+
@bindings.add(source: source, opts: opts)
|
173
179
|
|
174
180
|
self
|
175
181
|
end
|
@@ -190,6 +196,7 @@ module Bunny
|
|
190
196
|
# @api public
|
191
197
|
def unbind(source, opts = {})
|
192
198
|
@channel.exchange_unbind(source, self, opts)
|
199
|
+
@bindings.delete(source: source, opts: opts)
|
193
200
|
|
194
201
|
self
|
195
202
|
end
|
@@ -215,8 +222,11 @@ module Bunny
|
|
215
222
|
|
216
223
|
# @private
|
217
224
|
def recover_from_network_failure
|
218
|
-
|
219
|
-
|
225
|
+
declare! unless @options[:no_declare] ||predefined?
|
226
|
+
|
227
|
+
@bindings.each do |b|
|
228
|
+
bind(b[:source], b[:opts])
|
229
|
+
end
|
220
230
|
end
|
221
231
|
|
222
232
|
|
@@ -246,11 +256,6 @@ module Bunny
|
|
246
256
|
@channel.exchange_declare(@name, @type, @options)
|
247
257
|
end
|
248
258
|
|
249
|
-
# @private
|
250
|
-
def self.add_default_options(name, opts, block)
|
251
|
-
{ :exchange => name, :nowait => (block.nil? && !name.empty?) }.merge(opts)
|
252
|
-
end
|
253
|
-
|
254
259
|
# @private
|
255
260
|
def self.add_default_options(name, opts)
|
256
261
|
# :nowait is always false for Bunny
|
@@ -261,6 +266,7 @@ module Bunny
|
|
261
266
|
:passive => false,
|
262
267
|
:durable => false,
|
263
268
|
:auto_delete => false,
|
269
|
+
:internal => false,
|
264
270
|
:arguments => nil
|
265
271
|
}.merge(h)
|
266
272
|
else
|
data/lib/bunny/framing.rb
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bunny/versioned_delivery_tag"
|
4
|
+
|
5
|
+
module Bunny
|
6
|
+
# Wraps {AMQ::Protocol::Basic::GetOk} to
|
7
|
+
# provide access to the delivery properties as immutable hash as
|
8
|
+
# well as methods.
|
9
|
+
class GetResponse
|
10
|
+
|
11
|
+
#
|
12
|
+
# Behaviors
|
13
|
+
#
|
14
|
+
|
15
|
+
include Enumerable
|
16
|
+
|
17
|
+
#
|
18
|
+
# API
|
19
|
+
#
|
20
|
+
|
21
|
+
# @return [Bunny::Channel] Channel this basic.get-ok response is on
|
22
|
+
attr_reader :channel
|
23
|
+
|
24
|
+
# @private
|
25
|
+
def initialize(get_ok, channel)
|
26
|
+
@get_ok = get_ok
|
27
|
+
@hash = {
|
28
|
+
:delivery_tag => @get_ok.delivery_tag,
|
29
|
+
:redelivered => @get_ok.redelivered,
|
30
|
+
:exchange => @get_ok.exchange,
|
31
|
+
:routing_key => @get_ok.routing_key,
|
32
|
+
:channel => channel
|
33
|
+
}
|
34
|
+
@channel = channel
|
35
|
+
end
|
36
|
+
|
37
|
+
# Iterates over the delivery properties
|
38
|
+
# @see Enumerable#each
|
39
|
+
def each(*args, &block)
|
40
|
+
@hash.each(*args, &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Accesses delivery properties by key
|
44
|
+
# @see Hash#[]
|
45
|
+
def [](k)
|
46
|
+
@hash[k]
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Hash] Hash representation of this delivery info
|
50
|
+
def to_hash
|
51
|
+
@hash
|
52
|
+
end
|
53
|
+
|
54
|
+
# @private
|
55
|
+
def to_s
|
56
|
+
to_hash.to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
# @private
|
60
|
+
def inspect
|
61
|
+
to_hash.inspect
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [String] Delivery identifier that is used to acknowledge, reject and nack deliveries
|
65
|
+
def delivery_tag
|
66
|
+
@get_ok.delivery_tag
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [Boolean] true if this delivery is a redelivery (the message was requeued at least once)
|
70
|
+
def redelivered
|
71
|
+
@get_ok.redelivered
|
72
|
+
end
|
73
|
+
alias redelivered? redelivered
|
74
|
+
|
75
|
+
# @return [String] Name of the exchange this message was published to
|
76
|
+
def exchange
|
77
|
+
@get_ok.exchange
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [String] Routing key this message was published with
|
81
|
+
def routing_key
|
82
|
+
@get_ok.routing_key
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "thread"
|
2
4
|
require "amq/protocol/client"
|
3
5
|
require "amq/protocol/frame"
|
@@ -17,7 +19,7 @@ module Bunny
|
|
17
19
|
@logger = logger
|
18
20
|
@mutex = Monitor.new
|
19
21
|
|
20
|
-
@last_activity_time =
|
22
|
+
@last_activity_time = Bunny::Timestamp.monotonic
|
21
23
|
end
|
22
24
|
|
23
25
|
def start(period = 30)
|
@@ -29,6 +31,7 @@ module Bunny
|
|
29
31
|
@interval = [(period / 2) - 1, 0.4].max
|
30
32
|
|
31
33
|
@thread = Thread.new(&method(:run))
|
34
|
+
@thread.report_on_exception = false if @thread.respond_to?(:report_on_exception)
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
@@ -37,7 +40,7 @@ module Bunny
|
|
37
40
|
end
|
38
41
|
|
39
42
|
def signal_activity!
|
40
|
-
@last_activity_time =
|
43
|
+
@last_activity_time = Bunny::Timestamp.monotonic
|
41
44
|
end
|
42
45
|
|
43
46
|
protected
|
@@ -52,18 +55,18 @@ module Bunny
|
|
52
55
|
rescue IOError => ioe
|
53
56
|
@logger.error "I/O error in the hearbeat sender: #{ioe.message}"
|
54
57
|
stop
|
55
|
-
rescue Exception => e
|
58
|
+
rescue ::Exception => e
|
56
59
|
@logger.error "Error in the hearbeat sender: #{e.message}"
|
57
60
|
stop
|
58
61
|
end
|
59
62
|
end
|
60
63
|
|
61
64
|
def beat
|
62
|
-
now =
|
65
|
+
now = Bunny::Timestamp.monotonic
|
63
66
|
|
64
67
|
if now > (@last_activity_time + @interval)
|
65
|
-
@logger.debug "Sending a heartbeat, last activity time: #{@last_activity_time}, interval (s): #{@interval}"
|
66
|
-
@transport.write_without_timeout(AMQ::Protocol::HeartbeatFrame.encode)
|
68
|
+
@logger.debug { "Sending a heartbeat, last activity time: #{@last_activity_time}, interval (s): #{@interval}" }
|
69
|
+
@transport.write_without_timeout(AMQ::Protocol::HeartbeatFrame.encode, true)
|
67
70
|
end
|
68
71
|
end
|
69
72
|
end
|
data/lib/bunny/queue.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bunny/get_response"
|
2
4
|
|
3
5
|
module Bunny
|
4
6
|
# Represents AMQP 0.9.1 queue.
|
@@ -7,13 +9,27 @@ module Bunny
|
|
7
9
|
# @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
|
8
10
|
class Queue
|
9
11
|
|
10
|
-
include Bunny::Compatibility
|
11
|
-
|
12
|
-
|
13
12
|
#
|
14
13
|
# API
|
15
14
|
#
|
16
15
|
|
16
|
+
module Types
|
17
|
+
QUORUM = "quorum"
|
18
|
+
CLASSIC = "classic"
|
19
|
+
STREAM = "stream"
|
20
|
+
|
21
|
+
KNOWN = [CLASSIC, QUORUM, STREAM]
|
22
|
+
|
23
|
+
def self.known?(q_type)
|
24
|
+
KNOWN.include?(q_type)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module XArgs
|
29
|
+
MAX_LENGTH = "x-max-length",
|
30
|
+
QUEUE_TYPE = "x-queue-type"
|
31
|
+
end
|
32
|
+
|
17
33
|
# @return [Bunny::Channel] Channel this queue uses
|
18
34
|
attr_reader :channel
|
19
35
|
# @return [String] Queue name
|
@@ -21,33 +37,42 @@ module Bunny
|
|
21
37
|
# @return [Hash] Options this queue was created with
|
22
38
|
attr_reader :options
|
23
39
|
|
24
|
-
# @param [Bunny::Channel]
|
25
|
-
# backwards compatibility with 0.8.
|
40
|
+
# @param [Bunny::Channel] channel Channel this queue will use.
|
26
41
|
# @param [String] name Queue name. Pass an empty string to make RabbitMQ generate a unique one.
|
27
42
|
# @param [Hash] opts Queue properties
|
28
43
|
#
|
29
44
|
# @option opts [Boolean] :durable (false) Should this queue be durable?
|
30
45
|
# @option opts [Boolean] :auto_delete (false) Should this queue be automatically deleted when the last consumer disconnects?
|
31
46
|
# @option opts [Boolean] :exclusive (false) Should this queue be exclusive (only can be used by this connection, removed when the connection is closed)?
|
32
|
-
# @option opts [
|
47
|
+
# @option opts [String] :type (nil) Type of the declared queue (classic, quorum or stream)
|
48
|
+
# @option opts [Hash] :arguments (nil) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
33
49
|
#
|
34
50
|
# @see Bunny::Channel#queue
|
35
51
|
# @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
|
36
52
|
# @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
|
37
53
|
# @api public
|
38
|
-
def initialize(
|
54
|
+
def initialize(channel, name = AMQ::Protocol::EMPTY_STRING, opts = {})
|
39
55
|
# old Bunny versions pass a connection here. In that case,
|
40
56
|
# we just use default channel from it. MK.
|
41
|
-
@channel =
|
57
|
+
@channel = channel
|
42
58
|
@name = name
|
43
59
|
@options = self.class.add_default_options(name, opts)
|
44
|
-
@consumers = Hash.new
|
45
60
|
|
46
61
|
@durable = @options[:durable]
|
47
62
|
@exclusive = @options[:exclusive]
|
48
63
|
@server_named = @name.empty?
|
49
64
|
@auto_delete = @options[:auto_delete]
|
50
|
-
@
|
65
|
+
@type = @options[:type]
|
66
|
+
|
67
|
+
@arguments = if @type and !@type.empty? then
|
68
|
+
(@options[:arguments] || {}).merge({XArgs::QUEUE_TYPE => @type})
|
69
|
+
else
|
70
|
+
@options[:arguments]
|
71
|
+
end
|
72
|
+
verify_type!(@arguments)
|
73
|
+
# reassigns updated and verified arguments because Bunny::Channel#declare_queue
|
74
|
+
# accepts a map of options
|
75
|
+
@options[:arguments] = @arguments
|
51
76
|
|
52
77
|
@bindings = Array.new
|
53
78
|
|
@@ -92,6 +117,15 @@ module Bunny
|
|
92
117
|
@arguments
|
93
118
|
end
|
94
119
|
|
120
|
+
def to_s
|
121
|
+
oid = ("0x%x" % (self.object_id << 1))
|
122
|
+
"<#{self.class.name}:#{oid} @name=\"#{name}\" channel=#{@channel.to_s} @durable=#{@durable} @auto_delete=#{@auto_delete} @exclusive=#{@exclusive} @arguments=#{@arguments}>"
|
123
|
+
end
|
124
|
+
|
125
|
+
def inspect
|
126
|
+
to_s
|
127
|
+
end
|
128
|
+
|
95
129
|
# Binds queue to an exchange
|
96
130
|
#
|
97
131
|
# @param [Bunny::Exchange,String] exchange Exchange to bind to
|
@@ -151,9 +185,9 @@ module Bunny
|
|
151
185
|
#
|
152
186
|
# @param [Hash] opts Options
|
153
187
|
#
|
188
|
+
# @option opts [Boolean] :ack (false) [DEPRECATED] Use :manual_ack instead
|
154
189
|
# @option opts [Boolean] :manual_ack (false) Will this consumer use manual acknowledgements?
|
155
190
|
# @option opts [Boolean] :exclusive (false) Should this consumer be exclusive for this queue?
|
156
|
-
# @option opts [Boolean] :block (false) Should the call block calling thread?
|
157
191
|
# @option opts [#call] :on_cancellation Block to execute when this consumer is cancelled remotely (e.g. via the RabbitMQ Management plugin)
|
158
192
|
# @option opts [String] :consumer_tag Unique consumer identifier. It is usually recommended to let Bunny generate it for you.
|
159
193
|
# @option opts [Hash] :arguments ({}) Additional (optional) arguments, typically used by RabbitMQ extensions
|
@@ -162,17 +196,22 @@ module Bunny
|
|
162
196
|
# @api public
|
163
197
|
def subscribe(opts = {
|
164
198
|
:consumer_tag => @channel.generate_consumer_tag,
|
165
|
-
:
|
199
|
+
:manual_ack => false,
|
166
200
|
:exclusive => false,
|
167
201
|
:block => false,
|
168
202
|
:on_cancellation => nil
|
169
203
|
}, &block)
|
170
204
|
|
205
|
+
unless opts[:ack].nil?
|
206
|
+
warn "[DEPRECATION] `:ack` is deprecated. Please use `:manual_ack` instead."
|
207
|
+
opts[:manual_ack] = opts[:ack]
|
208
|
+
end
|
209
|
+
|
171
210
|
ctag = opts.fetch(:consumer_tag, @channel.generate_consumer_tag)
|
172
211
|
consumer = Consumer.new(@channel,
|
173
212
|
self,
|
174
213
|
ctag,
|
175
|
-
!
|
214
|
+
!opts[:manual_ack],
|
176
215
|
opts[:exclusive],
|
177
216
|
opts[:arguments])
|
178
217
|
|
@@ -207,7 +246,8 @@ module Bunny
|
|
207
246
|
|
208
247
|
# @param [Hash] opts Options
|
209
248
|
#
|
210
|
-
# @option opts [Boolean] :ack (false)
|
249
|
+
# @option opts [Boolean] :ack (false) [DEPRECATED] Use :manual_ack instead
|
250
|
+
# @option opts [Boolean] :manual_ack (false) Will the message be acknowledged manually?
|
211
251
|
#
|
212
252
|
# @return [Array] Triple of delivery info, message properties and message content.
|
213
253
|
# If the queue is empty, all three will be nils.
|
@@ -228,33 +268,34 @@ module Bunny
|
|
228
268
|
#
|
229
269
|
# puts "This is the message: " + payload + "\n\n"
|
230
270
|
# conn.close
|
231
|
-
def pop(opts = {:
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
block.call(delivery_info, properties, content)
|
236
|
-
else
|
237
|
-
[delivery_info, properties, content]
|
271
|
+
def pop(opts = {:manual_ack => false}, &block)
|
272
|
+
unless opts[:ack].nil?
|
273
|
+
warn "[DEPRECATION] `:ack` is deprecated. Please use `:manual_ack` instead."
|
274
|
+
opts[:manual_ack] = opts[:ack]
|
238
275
|
end
|
239
|
-
end
|
240
|
-
alias get pop
|
241
276
|
|
242
|
-
|
243
|
-
# (as a hash).
|
244
|
-
# @return [Hash]
|
245
|
-
# @deprecated
|
246
|
-
def pop_as_hash(opts = {:ack => false}, &block)
|
247
|
-
delivery_info, properties, content = @channel.basic_get(@name, opts)
|
248
|
-
|
249
|
-
result = {:header => properties, :payload => content, :delivery_details => delivery_info}
|
277
|
+
get_response, properties, content = @channel.basic_get(@name, opts)
|
250
278
|
|
251
279
|
if block
|
252
|
-
|
280
|
+
if properties
|
281
|
+
di = GetResponse.new(get_response, @channel)
|
282
|
+
mp = MessageProperties.new(properties)
|
283
|
+
|
284
|
+
block.call(di, mp, content)
|
285
|
+
else
|
286
|
+
block.call(nil, nil, nil)
|
287
|
+
end
|
253
288
|
else
|
254
|
-
|
289
|
+
if properties
|
290
|
+
di = GetResponse.new(get_response, @channel)
|
291
|
+
mp = MessageProperties.new(properties)
|
292
|
+
[di, mp, content]
|
293
|
+
else
|
294
|
+
[nil, nil, nil]
|
295
|
+
end
|
255
296
|
end
|
256
297
|
end
|
257
|
-
|
298
|
+
alias get pop
|
258
299
|
|
259
300
|
# Publishes a message to the queue via default exchange. Takes the same arguments
|
260
301
|
# as {Bunny::Exchange#publish}
|
@@ -313,6 +354,14 @@ module Bunny
|
|
313
354
|
s[:consumer_count]
|
314
355
|
end
|
315
356
|
|
357
|
+
def self.verify_type!(args0 = {})
|
358
|
+
# be extra defensive
|
359
|
+
args = args0 || {}
|
360
|
+
q_type = args["x-queue-type"] || args[:"x-queue-type"]
|
361
|
+
throw ArgumentError.new(
|
362
|
+
"unsupported queue type #{q_type.inspect}, supported ones: #{Types::KNOWN.join(', ')}") if (q_type and !Types.known?(q_type))
|
363
|
+
end
|
364
|
+
|
316
365
|
#
|
317
366
|
# Recovery
|
318
367
|
#
|
@@ -329,7 +378,7 @@ module Bunny
|
|
329
378
|
# TODO: inject and use logger
|
330
379
|
# puts "Recovering queue #{@name}"
|
331
380
|
begin
|
332
|
-
declare!
|
381
|
+
declare! unless @options[:no_declare]
|
333
382
|
|
334
383
|
@channel.register_queue(self)
|
335
384
|
rescue Exception => e
|
@@ -361,11 +410,6 @@ module Bunny
|
|
361
410
|
|
362
411
|
protected
|
363
412
|
|
364
|
-
# @private
|
365
|
-
def self.add_default_options(name, opts, block)
|
366
|
-
{ :queue => name, :nowait => (block.nil? && !name.empty?) }.merge(opts)
|
367
|
-
end
|
368
|
-
|
369
413
|
# @private
|
370
414
|
def self.add_default_options(name, opts)
|
371
415
|
# :nowait is always false for Bunny
|
@@ -383,5 +427,9 @@ module Bunny
|
|
383
427
|
h
|
384
428
|
end
|
385
429
|
end
|
430
|
+
|
431
|
+
def verify_type!(args)
|
432
|
+
self.class.verify_type!(args)
|
433
|
+
end
|
386
434
|
end
|
387
435
|
end
|