bunny 2.19.0 → 2.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +26 -32
- data/lib/bunny/channel.rb +86 -10
- data/lib/bunny/consumer.rb +2 -2
- data/lib/bunny/delivery_info.rb +1 -1
- data/lib/bunny/queue.rb +33 -2
- data/lib/bunny/session.rb +1 -1
- data/lib/bunny/transport.rb +30 -1
- data/lib/bunny/version.rb +1 -1
- data/lib/bunny.rb +45 -4
- metadata +4 -144
- data/spec/config/enabled_plugins +0 -1
- data/spec/config/rabbitmq.conf +0 -13
- data/spec/higher_level_api/integration/basic_ack_spec.rb +0 -230
- data/spec/higher_level_api/integration/basic_cancel_spec.rb +0 -142
- data/spec/higher_level_api/integration/basic_consume_spec.rb +0 -357
- 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 -80
- data/spec/higher_level_api/integration/basic_nack_spec.rb +0 -82
- data/spec/higher_level_api/integration/basic_publish_spec.rb +0 -74
- data/spec/higher_level_api/integration/basic_qos_spec.rb +0 -57
- data/spec/higher_level_api/integration/basic_reject_spec.rb +0 -152
- data/spec/higher_level_api/integration/basic_return_spec.rb +0 -33
- data/spec/higher_level_api/integration/channel_close_spec.rb +0 -66
- data/spec/higher_level_api/integration/channel_open_spec.rb +0 -57
- data/spec/higher_level_api/integration/connection_recovery_spec.rb +0 -483
- data/spec/higher_level_api/integration/connection_spec.rb +0 -589
- data/spec/higher_level_api/integration/connection_stop_spec.rb +0 -83
- data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +0 -128
- data/spec/higher_level_api/integration/dead_lettering_spec.rb +0 -75
- data/spec/higher_level_api/integration/exchange_bind_spec.rb +0 -31
- data/spec/higher_level_api/integration/exchange_declare_spec.rb +0 -237
- 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 -49
- 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 -191
- data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +0 -87
- data/spec/higher_level_api/integration/queue_bind_spec.rb +0 -109
- data/spec/higher_level_api/integration/queue_declare_spec.rb +0 -285
- 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 -255
- data/spec/higher_level_api/integration/toxiproxy_spec.rb +0 -76
- 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 -43
- data/spec/issues/issue202_spec.rb +0 -15
- data/spec/issues/issue224_spec.rb +0 -40
- data/spec/issues/issue465_spec.rb +0 -32
- data/spec/issues/issue549_spec.rb +0 -30
- data/spec/issues/issue609_spec.rb +0 -84
- data/spec/issues/issue78_spec.rb +0 -72
- data/spec/issues/issue83_spec.rb +0 -30
- data/spec/issues/issue97_attachment.json +0 -1
- data/spec/issues/issue97_spec.rb +0 -175
- data/spec/lower_level_api/integration/basic_cancel_spec.rb +0 -83
- data/spec/lower_level_api/integration/basic_consume_spec.rb +0 -99
- data/spec/spec_helper.rb +0 -47
- data/spec/stress/channel_close_stress_spec.rb +0 -64
- data/spec/stress/channel_open_stress_spec.rb +0 -84
- data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +0 -28
- data/spec/stress/concurrent_consumers_stress_spec.rb +0 -71
- data/spec/stress/concurrent_publishers_stress_spec.rb +0 -54
- data/spec/stress/connection_open_close_spec.rb +0 -52
- data/spec/stress/merry_go_round_spec.rb +0 -105
- data/spec/toxiproxy_helper.rb +0 -28
- 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/exchange_recovery_spec.rb +0 -39
- data/spec/unit/version_delivery_tag_spec.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 468bfc7996c3f5788b662177b34a05347cfcb62719dcf28ed80eda672353785b
|
4
|
+
data.tar.gz: 2bdfafeb9150f68fc6dbf63fdc9b14463c0f00cb0f7a9641f1b15ddf2e4cb56e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b51c187bd404eb6a57c5ce7dd061f25de84cff1f27873e38a751269410ee46a2f639a3b94b0e4f1544c9044850df9e8db5d45fe9a35d9ba2e7bd392f2290e72b
|
7
|
+
data.tar.gz: 863c430420bc560223e24e90fb259bfc537ef73c016b2089e14d1b73307f8564cf945ade393d36b0cfe4a259b4daec88f50ee12d0a6cb037d27ce5aab0466d64
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@ have any heavyweight dependencies.
|
|
7
7
|
|
8
8
|
## I Know What RabbitMQ and Bunny are, How Do I Get Started?
|
9
9
|
|
10
|
-
[Right here](
|
10
|
+
[Right here](https://www.rabbitmq.com/getstarted.html)!
|
11
11
|
|
12
12
|
|
13
13
|
## What is Bunny Good For?
|
@@ -47,7 +47,8 @@ Specific examples:
|
|
47
47
|
|
48
48
|
Modern Bunny versions support
|
49
49
|
|
50
|
-
* CRuby 2.
|
50
|
+
* CRuby 2.6 through 3.1 (inclusive)
|
51
|
+
* [TruffleRuby](https://www.graalvm.org/ruby/)
|
51
52
|
|
52
53
|
Bunny works sufficiently well on JRuby but there are known
|
53
54
|
JRuby bugs in versions prior to JRuby 9000 that cause high CPU burn. JRuby users should
|
@@ -58,8 +59,7 @@ Bunny `1.7.x` was the last version to support CRuby 1.9.3 and 1.8.7
|
|
58
59
|
|
59
60
|
## Supported RabbitMQ Versions
|
60
61
|
|
61
|
-
Bunny
|
62
|
-
Bunny `1.4.x` and earlier supports RabbitMQ 2.x and 3.x.
|
62
|
+
Modern Bunny releases target [currently supported RabbitMQ release series](https://www.rabbitmq.com/versions.html).
|
63
63
|
|
64
64
|
|
65
65
|
## Change Log
|
@@ -69,9 +69,8 @@ a stable public API.
|
|
69
69
|
|
70
70
|
Change logs per release series:
|
71
71
|
|
72
|
-
* [
|
73
|
-
* [2.
|
74
|
-
* [2.17.x](https://github.com/ruby-amqp/bunny/blob/2.17.x-stable/ChangeLog.md)
|
72
|
+
* [main](https://github.com/ruby-amqp/bunny/blob/main/ChangeLog.md) (most notable changes for all release series)
|
73
|
+
* [2.19.x](https://github.com/ruby-amqp/bunny/blob/2.19.x-stable/ChangeLog.md)
|
75
74
|
|
76
75
|
|
77
76
|
|
@@ -81,20 +80,20 @@ Change logs per release series:
|
|
81
80
|
|
82
81
|
[![Gem Version](https://badge.fury.io/rb/bunny.svg)](http://badge.fury.io/rb/bunny)
|
83
82
|
|
84
|
-
###
|
83
|
+
### Bundler Dependency
|
85
84
|
|
86
|
-
To
|
85
|
+
To use Bunny in a project managed with Bundler:
|
87
86
|
|
88
|
-
```
|
89
|
-
gem
|
87
|
+
``` ruby
|
88
|
+
gem "bunny", ">= 2.19.0"
|
90
89
|
```
|
91
90
|
|
92
|
-
###
|
91
|
+
### With Rubygems
|
93
92
|
|
94
|
-
To
|
93
|
+
To install Bunny with RubyGems:
|
95
94
|
|
96
|
-
```
|
97
|
-
gem
|
95
|
+
```
|
96
|
+
gem install bunny
|
98
97
|
```
|
99
98
|
|
100
99
|
|
@@ -103,7 +102,7 @@ gem "bunny", ">= 2.18.0"
|
|
103
102
|
Below is a small snippet that demonstrates how to publish
|
104
103
|
and synchronously consume ("pull API") messages with Bunny.
|
105
104
|
|
106
|
-
For a 15 minute tutorial using more practical examples, see [Getting Started with RabbitMQ and Ruby using Bunny](
|
105
|
+
For a 15 minute tutorial using more practical examples, see [Getting Started with RabbitMQ and Ruby using Bunny](https://www.rabbitmq.com/tutorials/tutorial-one-ruby.html).
|
107
106
|
|
108
107
|
``` ruby
|
109
108
|
require "bunny"
|
@@ -150,23 +149,25 @@ For a 15 minute tutorial using more practical examples, see [Getting Started wit
|
|
150
149
|
|
151
150
|
### Guides
|
152
151
|
|
153
|
-
Bunny documentation guides are
|
152
|
+
Bunny documentation guides are [under `docs/guides` in this repository](https://github.com/ruby-amqp/bunny/tree/main/docs/guides):
|
154
153
|
|
155
|
-
* [Queues and Consumers](
|
156
|
-
* [Exchanges and Publishers](
|
154
|
+
* [Queues and Consumers](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/queues.md)
|
155
|
+
* [Exchanges and Publishers](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/exchanges.md)
|
157
156
|
* [AMQP 0.9.1 Model Explained](http://www.rabbitmq.com/tutorials/amqp-concepts.html)
|
158
|
-
* [Connecting to RabbitMQ](
|
159
|
-
* [Error Handling and Recovery](
|
160
|
-
* [TLS/SSL Support](
|
161
|
-
* [Bindings](
|
162
|
-
* [Using RabbitMQ Extensions with Bunny](
|
163
|
-
* [Durability and Related Matters](
|
157
|
+
* [Connecting to RabbitMQ](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/connecting.md)
|
158
|
+
* [Error Handling and Recovery](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/error_handling.md)
|
159
|
+
* [TLS/SSL Support](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/tls.md)
|
160
|
+
* [Bindings](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/bindings.md)
|
161
|
+
* [Using RabbitMQ Extensions with Bunny](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/extensions.md)
|
162
|
+
* [Durability and Related Matters](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/durability.md)
|
164
163
|
|
165
164
|
Some highly relevant RabbitMQ documentation guides:
|
166
165
|
|
167
166
|
* [Connections](https://www.rabbitmq.com/connections.html)
|
168
167
|
* [Channels](https://www.rabbitmq.com/channels.html)
|
169
168
|
* [Queues](https://www.rabbitmq.com/queues.html)
|
169
|
+
* [Quorum queues](https://www.rabbitmq.com/quorum-queues.html)
|
170
|
+
* [Streams](https://rabbitmq.com/streams.html) (Bunny can perform basic operations on streams even though it does not implement the [RabbitMQ Stream protocol](https://github.com/rabbitmq/rabbitmq-server/blob/v3.10.x/deps/rabbitmq_stream/docs/PROTOCOL.adoc))
|
170
171
|
* [Publishers](https://www.rabbitmq.com/publishers.html)
|
171
172
|
* [Consumers](https://www.rabbitmq.com/consumers.html)
|
172
173
|
* Data safety: publisher and consumer [Confirmations](https://www.rabbitmq.com/confirms.html)
|
@@ -194,13 +195,6 @@ mailing list. Feel free to ask any questions that you may have.
|
|
194
195
|
[![Build Status](https://travis-ci.org/ruby-amqp/bunny.svg)](https://travis-ci.org/ruby-amqp/bunny/)
|
195
196
|
|
196
197
|
|
197
|
-
### News & Announcements on Twitter
|
198
|
-
|
199
|
-
To subscribe for announcements of releases, important changes and so on, please follow [@rubyamqp](https://twitter.com/#!/rubyamqp) on Twitter.
|
200
|
-
|
201
|
-
More detailed announcements can be found in the [RabbitMQ Ruby clients blog](http://blog.rubyrabbitmq.info).
|
202
|
-
|
203
|
-
|
204
198
|
### Reporting Issues
|
205
199
|
|
206
200
|
If you find a bug you understand well, poor default, incorrect or unclear piece of documentation,
|
data/lib/bunny/channel.rb
CHANGED
@@ -143,6 +143,10 @@ module Bunny
|
|
143
143
|
attr_reader :work_pool
|
144
144
|
# @return [Integer] Next publisher confirmations sequence index
|
145
145
|
attr_reader :next_publish_seq_no
|
146
|
+
# @return [Integer] Offset for the confirmations sequence index.
|
147
|
+
# This will be set to the current sequence index during automatic network failure recovery
|
148
|
+
# to keep the sequence monotonic for the user and abstract the reset from the protocol
|
149
|
+
attr_reader :delivery_tag_offset
|
146
150
|
# @return [Hash<String, Bunny::Queue>] Queue instances declared on this channel
|
147
151
|
attr_reader :queues
|
148
152
|
# @return [Hash<String, Bunny::Exchange>] Exchange instances declared on this channel
|
@@ -408,7 +412,7 @@ module Bunny
|
|
408
412
|
# @option opts [Boolean] :durable (false) Should this queue be durable?
|
409
413
|
# @option opts [Boolean] :auto-delete (false) Should this queue be automatically deleted when the last consumer disconnects?
|
410
414
|
# @option opts [Boolean] :exclusive (false) Should this queue be exclusive (only can be used by this connection, removed when the connection is closed)?
|
411
|
-
# @option opts [
|
415
|
+
# @option opts [Hash] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
412
416
|
#
|
413
417
|
# @return [Bunny::Queue] Queue that was declared or looked up in the cache
|
414
418
|
# @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
|
@@ -422,6 +426,73 @@ module Bunny
|
|
422
426
|
register_queue(q)
|
423
427
|
end
|
424
428
|
|
429
|
+
# Declares a new client-named quorum queue.
|
430
|
+
#
|
431
|
+
# @param [String] name Queue name. Empty (server-generated) names are not supported by this method.
|
432
|
+
# @param [Hash] opts Queue properties and other options. Durability, exclusivity, auto-deletion options will be ignored.
|
433
|
+
#
|
434
|
+
# @option opts [Hash] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
435
|
+
#
|
436
|
+
# @return [Bunny::Queue] Queue that was declared
|
437
|
+
# @see #durable_queue
|
438
|
+
# @see #queue
|
439
|
+
# @api public
|
440
|
+
def quorum_queue(name, opts = {})
|
441
|
+
throw ArgumentError.new("quorum queue name must not be nil") if name.nil?
|
442
|
+
throw ArgumentError.new("quorum queue name must not be empty (server-named QQs do not make sense)") if name.empty?
|
443
|
+
|
444
|
+
durable_queue(name, Bunny::Queue::Types::QUORUM, opts)
|
445
|
+
end
|
446
|
+
|
447
|
+
# Declares a new client-named stream (that Bunny can use as if it was a queue).
|
448
|
+
# Note that Bunny would still use AMQP 0-9-1 to perform operations on this "queue".
|
449
|
+
# To use stream-specific operations and to gain from stream protocol efficiency and partitioning,
|
450
|
+
# use a Ruby client for the RabbitMQ stream protocol.
|
451
|
+
#
|
452
|
+
# @param [String] name Stream name. Empty (server-generated) names are not supported by this method.
|
453
|
+
# @param [Hash] opts Queue properties and other options. Durability, exclusivity, auto-deletion options will be ignored.
|
454
|
+
#
|
455
|
+
# @option opts [Hash] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
456
|
+
#
|
457
|
+
#
|
458
|
+
# @return [Bunny::Queue] Queue that was declared
|
459
|
+
# @see #durable_queue
|
460
|
+
# @see #queue
|
461
|
+
# @api public
|
462
|
+
def stream(name, opts = {})
|
463
|
+
throw ArgumentError.new("stream name must not be nil") if name.nil?
|
464
|
+
throw ArgumentError.new("stream name must not be empty (server-named QQs do not make sense)") if name.empty?
|
465
|
+
|
466
|
+
durable_queue(name, Bunny::Queue::Types::STREAM, opts)
|
467
|
+
end
|
468
|
+
|
469
|
+
# Declares a new server-named queue that is automatically deleted when the
|
470
|
+
# connection is closed.
|
471
|
+
#
|
472
|
+
# @param [String] name Queue name. Empty (server-generated) names are not supported by this method.
|
473
|
+
# @param [Hash] opts Queue properties and other options. Durability, exclusivity, auto-deletion options will be ignored.
|
474
|
+
#
|
475
|
+
# @option opts [Hash] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
476
|
+
#
|
477
|
+
# @return [Bunny::Queue] Queue that was declared
|
478
|
+
# @see #queue
|
479
|
+
# @api public
|
480
|
+
def durable_queue(name, type = "classic", opts = {})
|
481
|
+
throw ArgumentError.new("queue name must not be nil") if name.nil?
|
482
|
+
throw ArgumentError.new("queue name must not be empty (server-named durable queues do not make sense)") if name.empty?
|
483
|
+
|
484
|
+
final_opts = opts.merge({
|
485
|
+
:type => type,
|
486
|
+
:durable => true,
|
487
|
+
# exclusive or auto-delete QQs do not make much sense
|
488
|
+
:exclusive => false,
|
489
|
+
:auto_delete => false
|
490
|
+
})
|
491
|
+
q = find_queue(name) || Bunny::Queue.new(self, name, final_opts)
|
492
|
+
|
493
|
+
register_queue(q)
|
494
|
+
end
|
495
|
+
|
425
496
|
# Declares a new server-named queue that is automatically deleted when the
|
426
497
|
# connection is closed.
|
427
498
|
#
|
@@ -1525,12 +1596,15 @@ module Bunny
|
|
1525
1596
|
|
1526
1597
|
# Recovers publisher confirms mode. Used by the Automatic Network Failure
|
1527
1598
|
# Recovery feature.
|
1599
|
+
# Set the offset to the previous publish sequence index as the protocol will reset the index to after recovery.
|
1528
1600
|
#
|
1529
1601
|
# @api plugin
|
1530
1602
|
def recover_confirm_mode
|
1531
1603
|
if using_publisher_confirmations?
|
1532
|
-
@
|
1533
|
-
|
1604
|
+
@unconfirmed_set_mutex.synchronize do
|
1605
|
+
@unconfirmed_set.clear
|
1606
|
+
@delivery_tag_offset = @next_publish_seq_no - 1
|
1607
|
+
end
|
1534
1608
|
confirm_select(@confirms_callback)
|
1535
1609
|
end
|
1536
1610
|
end
|
@@ -1599,7 +1673,7 @@ module Bunny
|
|
1599
1673
|
|
1600
1674
|
# @return [String] Brief human-readable representation of the channel
|
1601
1675
|
def to_s
|
1602
|
-
"#<#{self.class.name}:#{object_id} @id=#{self.number} @connection=#{@connection.to_s}
|
1676
|
+
"#<#{self.class.name}:#{object_id} @id=#{self.number} @connection=#{@connection.to_s} @open=#{open?}>"
|
1603
1677
|
end
|
1604
1678
|
|
1605
1679
|
def inspect
|
@@ -1663,7 +1737,7 @@ module Bunny
|
|
1663
1737
|
if !pending_server_named_queue_declaration?
|
1664
1738
|
# this response is for an outdated/overwritten
|
1665
1739
|
# queue.declare, drop it
|
1666
|
-
@logger.warn "Received a queue.declare-ok response for a mismatching queue (#{method.queue} instead of #{@pending_queue_declare_name}) on channel #{@id} possibly due to a timeout, ignoring it"
|
1740
|
+
@logger.warn "Received a queue.declare-ok response for a mismatching queue (#{method.queue} instead of #{@pending_queue_declare_name}) on channel #{@id}, possibly due to concurrent channel use or a timeout, ignoring it"
|
1667
1741
|
end
|
1668
1742
|
end
|
1669
1743
|
when AMQ::Protocol::Queue::DeleteOk then
|
@@ -1786,14 +1860,16 @@ module Bunny
|
|
1786
1860
|
end
|
1787
1861
|
end
|
1788
1862
|
|
1863
|
+
# Handle delivery tag offset calculations to keep the the delivery tag monotonic after a reset
|
1864
|
+
# due to automatic network failure recovery. @unconfirmed_set contains indices already offsetted.
|
1789
1865
|
# @private
|
1790
1866
|
def handle_ack_or_nack(delivery_tag_before_offset, multiple, nack)
|
1791
|
-
delivery_tag = delivery_tag_before_offset + @delivery_tag_offset
|
1792
|
-
confirmed_range_start = multiple ? @delivery_tag_offset + @unconfirmed_set.min : delivery_tag
|
1793
|
-
confirmed_range_end = delivery_tag
|
1794
|
-
confirmed_range = (confirmed_range_start..confirmed_range_end)
|
1795
|
-
|
1796
1867
|
@unconfirmed_set_mutex.synchronize do
|
1868
|
+
delivery_tag = delivery_tag_before_offset + @delivery_tag_offset
|
1869
|
+
confirmed_range_start = multiple ? @unconfirmed_set.min : delivery_tag
|
1870
|
+
confirmed_range_end = delivery_tag
|
1871
|
+
confirmed_range = (confirmed_range_start..confirmed_range_end)
|
1872
|
+
|
1797
1873
|
if nack
|
1798
1874
|
@nacked_set.merge(@unconfirmed_set & confirmed_range)
|
1799
1875
|
end
|
data/lib/bunny/consumer.rb
CHANGED
@@ -86,12 +86,12 @@ module Bunny
|
|
86
86
|
|
87
87
|
# @return [String] More detailed human-readable string representation of this consumer
|
88
88
|
def inspect
|
89
|
-
"#<#{self.class.name}:#{object_id} @channel_id=#{@channel.number} @queue=#{self.queue_name}
|
89
|
+
"#<#{self.class.name}:#{object_id} @channel_id=#{@channel.number} @queue=#{self.queue_name} @consumer_tag=#{@consumer_tag} @exclusive=#{@exclusive} @no_ack=#{@no_ack}>"
|
90
90
|
end
|
91
91
|
|
92
92
|
# @return [String] Brief human-readable string representation of this consumer
|
93
93
|
def to_s
|
94
|
-
"#<#{self.class.name}:#{object_id} @channel_id=#{@channel.number} @queue=#{self.queue_name}
|
94
|
+
"#<#{self.class.name}:#{object_id} @channel_id=#{@channel.number} @queue=#{self.queue_name} @consumer_tag=#{@consumer_tag}>"
|
95
95
|
end
|
96
96
|
|
97
97
|
# @return [Boolean] true if this consumer uses automatic acknowledgement mode
|
data/lib/bunny/delivery_info.rb
CHANGED
data/lib/bunny/queue.rb
CHANGED
@@ -11,6 +11,23 @@ module Bunny
|
|
11
11
|
# API
|
12
12
|
#
|
13
13
|
|
14
|
+
module Types
|
15
|
+
QUORUM = "quorum"
|
16
|
+
CLASSIC = "classic"
|
17
|
+
STREAM = "stream"
|
18
|
+
|
19
|
+
KNOWN = [CLASSIC, QUORUM, STREAM]
|
20
|
+
|
21
|
+
def self.known?(q_type)
|
22
|
+
KNOWN.include?(q_type)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module XArgs
|
27
|
+
MAX_LENGTH = "x-max-length",
|
28
|
+
QUEUE_TYPE = "x-queue-type"
|
29
|
+
end
|
30
|
+
|
14
31
|
# @return [Bunny::Channel] Channel this queue uses
|
15
32
|
attr_reader :channel
|
16
33
|
# @return [String] Queue name
|
@@ -25,7 +42,8 @@ module Bunny
|
|
25
42
|
# @option opts [Boolean] :durable (false) Should this queue be durable?
|
26
43
|
# @option opts [Boolean] :auto_delete (false) Should this queue be automatically deleted when the last consumer disconnects?
|
27
44
|
# @option opts [Boolean] :exclusive (false) Should this queue be exclusive (only can be used by this connection, removed when the connection is closed)?
|
28
|
-
# @option opts [
|
45
|
+
# @option opts [String] :type (nil) Type of the declared queue (classic, quorum or stream)
|
46
|
+
# @option opts [Hash] :arguments (nil) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
29
47
|
#
|
30
48
|
# @see Bunny::Channel#queue
|
31
49
|
# @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
|
@@ -42,7 +60,14 @@ module Bunny
|
|
42
60
|
@exclusive = @options[:exclusive]
|
43
61
|
@server_named = @name.empty?
|
44
62
|
@auto_delete = @options[:auto_delete]
|
45
|
-
@
|
63
|
+
@type = @options[:type]
|
64
|
+
|
65
|
+
@arguments = if @type and !@type.empty? then
|
66
|
+
(@options[:arguments] || {}).merge({XArgs::QUEUE_TYPE => @type})
|
67
|
+
else
|
68
|
+
@options[:arguments]
|
69
|
+
end
|
70
|
+
verify_type!(@arguments)
|
46
71
|
|
47
72
|
@bindings = Array.new
|
48
73
|
|
@@ -389,5 +414,11 @@ module Bunny
|
|
389
414
|
h
|
390
415
|
end
|
391
416
|
end
|
417
|
+
|
418
|
+
def verify_type!(args)
|
419
|
+
q_type = (args || {})["x-queue-type"]
|
420
|
+
throw ArgumentError.new(
|
421
|
+
"unsupported queue type #{q_type.inspect}, supported ones: #{Types::KNOWN.join(', ')}") if (q_type and !Types.known?(q_type))
|
422
|
+
end
|
392
423
|
end
|
393
424
|
end
|
data/lib/bunny/session.rb
CHANGED
@@ -109,7 +109,7 @@ module Bunny
|
|
109
109
|
# @option connection_string_or_opts [String] :tls_key (nil) Path to client TLS/SSL private key file (.pem)
|
110
110
|
# @option connection_string_or_opts [Array<String>] :tls_ca_certificates Array of paths to TLS/SSL CA files (.pem), by default detected from OpenSSL configuration
|
111
111
|
# @option connection_string_or_opts [String] :verify_peer (true) Whether TLS peer verification should be performed
|
112
|
-
# @option connection_string_or_opts [Symbol] :
|
112
|
+
# @option connection_string_or_opts [Symbol] :tls_protocol (negotiated) What TLS version should be used (:TLSv1, :TLSv1_1, or :TLSv1_2)
|
113
113
|
# @option connection_string_or_opts [Integer] :channel_max (2047) Maximum number of channels allowed on this connection, minus 1 to account for the special channel 0.
|
114
114
|
# @option connection_string_or_opts [Integer] :continuation_timeout (15000) Timeout for client operations that expect a response (e.g. {Bunny::Queue#get}), in milliseconds.
|
115
115
|
# @option connection_string_or_opts [Integer] :connection_timeout (30) Timeout in seconds for connecting to the server.
|
data/lib/bunny/transport.rb
CHANGED
@@ -25,6 +25,23 @@ module Bunny
|
|
25
25
|
DEFAULT_READ_TIMEOUT = 30.0
|
26
26
|
DEFAULT_WRITE_TIMEOUT = 30.0
|
27
27
|
|
28
|
+
# mimics METHODS_MAP in ssl.rb but also lists TLS 1.3
|
29
|
+
# and string constants
|
30
|
+
TLS_VERSION_ALIASES = {
|
31
|
+
TLSv1: OpenSSL::SSL::TLS1_VERSION,
|
32
|
+
TLSv1_1: OpenSSL::SSL::TLS1_1_VERSION,
|
33
|
+
TLSv1_2: OpenSSL::SSL::TLS1_2_VERSION,
|
34
|
+
TLSv1_3: OpenSSL::SSL::TLS1_3_VERSION,
|
35
|
+
"1.0": OpenSSL::SSL::TLS1_VERSION,
|
36
|
+
"1.1": OpenSSL::SSL::TLS1_1_VERSION,
|
37
|
+
"1.2": OpenSSL::SSL::TLS1_2_VERSION,
|
38
|
+
"1.3": OpenSSL::SSL::TLS1_3_VERSION,
|
39
|
+
OpenSSL::SSL::TLS1_VERSION => OpenSSL::SSL::TLS1_VERSION,
|
40
|
+
OpenSSL::SSL::TLS1_1_VERSION => OpenSSL::SSL::TLS1_1_VERSION,
|
41
|
+
OpenSSL::SSL::TLS1_2_VERSION => OpenSSL::SSL::TLS1_2_VERSION,
|
42
|
+
OpenSSL::SSL::TLS1_3_VERSION => OpenSSL::SSL::TLS1_3_VERSION
|
43
|
+
}.freeze
|
44
|
+
|
28
45
|
attr_reader :session, :host, :port, :socket, :connect_timeout, :read_timeout, :write_timeout, :disconnect_timeout
|
29
46
|
attr_reader :tls_context, :verify_peer, :tls_ca_certificates, :tls_certificate_path, :tls_key_path
|
30
47
|
|
@@ -491,7 +508,11 @@ but prone to man-in-the-middle attacks. Please set verify_peer: true in producti
|
|
491
508
|
end
|
492
509
|
|
493
510
|
ssl_version = opts[:tls_protocol] || opts[:ssl_version] || :TLSv1_2
|
494
|
-
|
511
|
+
if ssl_version
|
512
|
+
v = tls_version_constant(ssl_version)
|
513
|
+
ctx.min_version = v
|
514
|
+
ctx.max_version = v
|
515
|
+
end
|
495
516
|
|
496
517
|
ctx
|
497
518
|
end
|
@@ -519,6 +540,14 @@ but prone to man-in-the-middle attacks. Please set verify_peer: true in producti
|
|
519
540
|
end
|
520
541
|
end
|
521
542
|
|
543
|
+
|
544
|
+
def tls_version_constant(value)
|
545
|
+
# OpenSSL::SSL::TLS1_3_VERSION and similar constants
|
546
|
+
# are just integers, so use the value itself as fallback since
|
547
|
+
# there is no class to case switch on
|
548
|
+
TLS_VERSION_ALIASES[value] || value
|
549
|
+
end
|
550
|
+
|
522
551
|
def timeout_from(options)
|
523
552
|
options[:connect_timeout] || options[:connection_timeout] || options[:timeout] || DEFAULT_CONNECTION_TIMEOUT
|
524
553
|
end
|
data/lib/bunny/version.rb
CHANGED
data/lib/bunny.rb
CHANGED
@@ -53,17 +53,58 @@ module Bunny
|
|
53
53
|
# Instantiates a new connection. The actual network
|
54
54
|
# connection is started with {Bunny::Session#start}
|
55
55
|
#
|
56
|
+
# @param [String, Hash] connection_string_or_opts Connection string or a hash of connection options
|
57
|
+
# @param [Hash] optz Extra options not related to connection
|
58
|
+
#
|
59
|
+
# @option connection_string_or_opts [String] :host ("127.0.0.1") Hostname or IP address to connect to
|
60
|
+
# @option connection_string_or_opts [Array<String>] :hosts (["127.0.0.1"]) list of hostname or IP addresses to select hostname from when connecting
|
61
|
+
# @option connection_string_or_opts [Array<String>] :addresses (["127.0.0.1:5672"]) list of addresses to select hostname and port from when connecting
|
62
|
+
# @option connection_string_or_opts [Integer] :port (5672) Port RabbitMQ listens on
|
63
|
+
# @option connection_string_or_opts [String] :username ("guest") Username
|
64
|
+
# @option connection_string_or_opts [String] :password ("guest") Password
|
65
|
+
# @option connection_string_or_opts [String] :vhost ("/") Virtual host to use
|
66
|
+
# @option connection_string_or_opts [Integer, Symbol] :heartbeat (:server) Heartbeat timeout to offer to the server. :server means use the value suggested by RabbitMQ. 0 means heartbeats and socket read timeouts will be disabled (not recommended).
|
67
|
+
# @option connection_string_or_opts [Integer] :network_recovery_interval (4) Recovery interval periodic network recovery will use. This includes initial pause after network failure.
|
68
|
+
# @option connection_string_or_opts [Boolean] :tls (false) Should TLS/SSL be used?
|
69
|
+
# @option connection_string_or_opts [String] :tls_cert (nil) Path to client TLS/SSL certificate file (.pem)
|
70
|
+
# @option connection_string_or_opts [String] :tls_key (nil) Path to client TLS/SSL private key file (.pem)
|
71
|
+
# @option connection_string_or_opts [Array<String>] :tls_ca_certificates Array of paths to TLS/SSL CA files (.pem), by default detected from OpenSSL configuration
|
72
|
+
# @option connection_string_or_opts [String] :verify_peer (true) Whether TLS peer verification should be performed
|
73
|
+
# @option connection_string_or_opts [Symbol] :tls_protocol (negotiated) What TLS version should be used (:TLSv1, :TLSv1_1, or :TLSv1_2)
|
74
|
+
# @option connection_string_or_opts [Integer] :channel_max (2047) Maximum number of channels allowed on this connection, minus 1 to account for the special channel 0.
|
75
|
+
# @option connection_string_or_opts [Integer] :continuation_timeout (15000) Timeout for client operations that expect a response (e.g. {Bunny::Queue#get}), in milliseconds.
|
76
|
+
# @option connection_string_or_opts [Integer] :connection_timeout (30) Timeout in seconds for connecting to the server.
|
77
|
+
# @option connection_string_or_opts [Integer] :read_timeout (30) TCP socket read timeout in seconds. If heartbeats are disabled this will be ignored.
|
78
|
+
# @option connection_string_or_opts [Integer] :write_timeout (30) TCP socket write timeout in seconds.
|
79
|
+
# @option connection_string_or_opts [Proc] :hosts_shuffle_strategy a callable that reorders a list of host strings, defaults to Array#shuffle
|
80
|
+
# @option connection_string_or_opts [Proc] :recovery_completed a callable that will be called when a network recovery is performed
|
81
|
+
# @option connection_string_or_opts [Logger] :logger The logger. If missing, one is created using :log_file and :log_level.
|
82
|
+
# @option connection_string_or_opts [IO, String] :log_file The file or path to use when creating a logger. Defaults to STDOUT.
|
83
|
+
# @option connection_string_or_opts [IO, String] :logfile DEPRECATED: use :log_file instead. The file or path to use when creating a logger. Defaults to STDOUT.
|
84
|
+
# @option connection_string_or_opts [Integer] :log_level The log level to use when creating a logger. Defaults to LOGGER::WARN
|
85
|
+
# @option connection_string_or_opts [Boolean] :automatically_recover (true) Should automatically recover from network failures?
|
86
|
+
# @option connection_string_or_opts [Integer] :recovery_attempts (nil) Max number of recovery attempts, nil means forever
|
87
|
+
# @option connection_string_or_opts [Integer] :reset_recovery_attempts_after_reconnection (true) Should recovery attempt counter be reset after successful reconnection? When set to false, the attempt counter will last through the entire lifetime of the connection object.
|
88
|
+
# @option connection_string_or_opts [Proc] :recovery_attempt_started (nil) Will be called before every connection recovery attempt
|
89
|
+
# @option connection_string_or_opts [Proc] :recovery_completed (nil) Will be called after successful connection recovery
|
90
|
+
# @option connection_string_or_opts [Boolean] :recover_from_connection_close (true) Should this connection recover after receiving a server-sent connection.close (e.g. connection was force closed)?
|
91
|
+
# @option connection_string_or_opts [Object] :session_error_handler (Thread.current) Object which responds to #raise that will act as a session error handler. Defaults to Thread.current, which will raise asynchronous exceptions in the thread that created the session.
|
92
|
+
#
|
93
|
+
# @option optz [String] :auth_mechanism ("PLAIN") Authentication mechanism, PLAIN or EXTERNAL
|
94
|
+
# @option optz [String] :locale ("PLAIN") Locale RabbitMQ should use
|
95
|
+
# @option optz [String] :connection_name (nil) Client-provided connection name, if any. Note that the value returned does not uniquely identify a connection and cannot be used as a connection identifier in HTTP API requests.
|
96
|
+
#
|
56
97
|
# @return [Bunny::Session]
|
57
98
|
# @see Bunny::Session#start
|
58
99
|
# @see http://rubybunny.info/articles/getting_started.html
|
59
100
|
# @see http://rubybunny.info/articles/connecting.html
|
60
101
|
# @api public
|
61
|
-
def self.new(connection_string_or_opts = ENV['RABBITMQ_URL'],
|
62
|
-
if connection_string_or_opts.respond_to?(:keys) &&
|
63
|
-
|
102
|
+
def self.new(connection_string_or_opts = ENV['RABBITMQ_URL'], optz = {})
|
103
|
+
if connection_string_or_opts.respond_to?(:keys) && optz.empty?
|
104
|
+
optz = connection_string_or_opts
|
64
105
|
end
|
65
106
|
|
66
|
-
conn = Session.new(connection_string_or_opts,
|
107
|
+
conn = Session.new(connection_string_or_opts, optz)
|
67
108
|
@default_connection ||= conn
|
68
109
|
|
69
110
|
conn
|