bunny 2.19.0 → 2.20.3
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 +31 -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 +36 -2
- data/lib/bunny/session.rb +7 -3
- data/lib/bunny/transport.rb +37 -1
- data/lib/bunny/version.rb +1 -1
- data/lib/bunny.rb +45 -4
- metadata +5 -145
- 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: '0638b435d0f724c5b9566797df9ba50e94144f0bb82f60b01e5d794bce868512'
|
|
4
|
+
data.tar.gz: c278e7122a90653738ff68b845509873ed0e7ca7b5759e0a33a7157725bcf650
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 44e1c56c0500d2e375a22e6349401e25d9e1c8f9e553b91df0ed4ac07ee80167cd50e28f6191e549961a31c7795e07a740949b72c971178b2f35060a221cc312
|
|
7
|
+
data.tar.gz: c0cbd8f1d0d6b6973f6ba6e3cc6140dbaa6843fe18cb00372e5b3a01bbdad5f1c265867b8314937ed711671266fb14fb281bbf739b2510a91fad4404b6ba4042
|
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,13 @@ 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/)
|
|
52
|
+
|
|
53
|
+
For environments that use TLS, Bunny expects Ruby installations to use a recent enough OpenSSL version that
|
|
54
|
+
**includes support for TLS 1.3**.
|
|
55
|
+
|
|
56
|
+
### JRuby
|
|
51
57
|
|
|
52
58
|
Bunny works sufficiently well on JRuby but there are known
|
|
53
59
|
JRuby bugs in versions prior to JRuby 9000 that cause high CPU burn. JRuby users should
|
|
@@ -58,8 +64,7 @@ Bunny `1.7.x` was the last version to support CRuby 1.9.3 and 1.8.7
|
|
|
58
64
|
|
|
59
65
|
## Supported RabbitMQ Versions
|
|
60
66
|
|
|
61
|
-
Bunny
|
|
62
|
-
Bunny `1.4.x` and earlier supports RabbitMQ 2.x and 3.x.
|
|
67
|
+
Modern Bunny releases target [currently supported RabbitMQ release series](https://www.rabbitmq.com/versions.html).
|
|
63
68
|
|
|
64
69
|
|
|
65
70
|
## Change Log
|
|
@@ -69,9 +74,8 @@ a stable public API.
|
|
|
69
74
|
|
|
70
75
|
Change logs per release series:
|
|
71
76
|
|
|
72
|
-
* [
|
|
73
|
-
* [2.
|
|
74
|
-
* [2.17.x](https://github.com/ruby-amqp/bunny/blob/2.17.x-stable/ChangeLog.md)
|
|
77
|
+
* [main](https://github.com/ruby-amqp/bunny/blob/main/ChangeLog.md) (most notable changes for all release series)
|
|
78
|
+
* [2.19.x](https://github.com/ruby-amqp/bunny/blob/2.19.x-stable/ChangeLog.md)
|
|
75
79
|
|
|
76
80
|
|
|
77
81
|
|
|
@@ -81,20 +85,20 @@ Change logs per release series:
|
|
|
81
85
|
|
|
82
86
|
[](http://badge.fury.io/rb/bunny)
|
|
83
87
|
|
|
84
|
-
###
|
|
88
|
+
### Bundler Dependency
|
|
85
89
|
|
|
86
|
-
To
|
|
90
|
+
To use Bunny in a project managed with Bundler:
|
|
87
91
|
|
|
88
|
-
```
|
|
89
|
-
gem
|
|
92
|
+
``` ruby
|
|
93
|
+
gem "bunny", ">= 2.19.0"
|
|
90
94
|
```
|
|
91
95
|
|
|
92
|
-
###
|
|
96
|
+
### With Rubygems
|
|
93
97
|
|
|
94
|
-
To
|
|
98
|
+
To install Bunny with RubyGems:
|
|
95
99
|
|
|
96
|
-
```
|
|
97
|
-
gem
|
|
100
|
+
```
|
|
101
|
+
gem install bunny
|
|
98
102
|
```
|
|
99
103
|
|
|
100
104
|
|
|
@@ -103,7 +107,7 @@ gem "bunny", ">= 2.18.0"
|
|
|
103
107
|
Below is a small snippet that demonstrates how to publish
|
|
104
108
|
and synchronously consume ("pull API") messages with Bunny.
|
|
105
109
|
|
|
106
|
-
For a 15 minute tutorial using more practical examples, see [Getting Started with RabbitMQ and Ruby using Bunny](
|
|
110
|
+
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
111
|
|
|
108
112
|
``` ruby
|
|
109
113
|
require "bunny"
|
|
@@ -150,23 +154,25 @@ For a 15 minute tutorial using more practical examples, see [Getting Started wit
|
|
|
150
154
|
|
|
151
155
|
### Guides
|
|
152
156
|
|
|
153
|
-
Bunny documentation guides are
|
|
157
|
+
Bunny documentation guides are [under `docs/guides` in this repository](https://github.com/ruby-amqp/bunny/tree/main/docs/guides):
|
|
154
158
|
|
|
155
|
-
* [Queues and Consumers](
|
|
156
|
-
* [Exchanges and Publishers](
|
|
159
|
+
* [Queues and Consumers](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/queues.md)
|
|
160
|
+
* [Exchanges and Publishers](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/exchanges.md)
|
|
157
161
|
* [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](
|
|
162
|
+
* [Connecting to RabbitMQ](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/connecting.md)
|
|
163
|
+
* [Error Handling and Recovery](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/error_handling.md)
|
|
164
|
+
* [TLS/SSL Support](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/tls.md)
|
|
165
|
+
* [Bindings](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/bindings.md)
|
|
166
|
+
* [Using RabbitMQ Extensions with Bunny](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/extensions.md)
|
|
167
|
+
* [Durability and Related Matters](https://github.com/ruby-amqp/bunny/tree/main/docs/guides/durability.md)
|
|
164
168
|
|
|
165
169
|
Some highly relevant RabbitMQ documentation guides:
|
|
166
170
|
|
|
167
171
|
* [Connections](https://www.rabbitmq.com/connections.html)
|
|
168
172
|
* [Channels](https://www.rabbitmq.com/channels.html)
|
|
169
173
|
* [Queues](https://www.rabbitmq.com/queues.html)
|
|
174
|
+
* [Quorum queues](https://www.rabbitmq.com/quorum-queues.html)
|
|
175
|
+
* [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
176
|
* [Publishers](https://www.rabbitmq.com/publishers.html)
|
|
171
177
|
* [Consumers](https://www.rabbitmq.com/consumers.html)
|
|
172
178
|
* Data safety: publisher and consumer [Confirmations](https://www.rabbitmq.com/confirms.html)
|
|
@@ -194,13 +200,6 @@ mailing list. Feel free to ask any questions that you may have.
|
|
|
194
200
|
[](https://travis-ci.org/ruby-amqp/bunny/)
|
|
195
201
|
|
|
196
202
|
|
|
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
203
|
### Reporting Issues
|
|
205
204
|
|
|
206
205
|
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,17 @@ 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)
|
|
71
|
+
# reassigns updated and verified arguments because Bunny::Channel#declare_queue
|
|
72
|
+
# accepts a map of options
|
|
73
|
+
@options[:arguments] = @arguments
|
|
46
74
|
|
|
47
75
|
@bindings = Array.new
|
|
48
76
|
|
|
@@ -389,5 +417,11 @@ module Bunny
|
|
|
389
417
|
h
|
|
390
418
|
end
|
|
391
419
|
end
|
|
420
|
+
|
|
421
|
+
def verify_type!(args)
|
|
422
|
+
q_type = (args || {})["x-queue-type"]
|
|
423
|
+
throw ArgumentError.new(
|
|
424
|
+
"unsupported queue type #{q_type.inspect}, supported ones: #{Types::KNOWN.join(', ')}") if (q_type and !Types.known?(q_type))
|
|
425
|
+
end
|
|
392
426
|
end
|
|
393
427
|
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.
|
|
@@ -671,8 +671,12 @@ module Bunny
|
|
|
671
671
|
# avoid doing that while holding a mutex lock. MK.
|
|
672
672
|
ch.handle_method(method)
|
|
673
673
|
ensure
|
|
674
|
-
|
|
675
|
-
|
|
674
|
+
if ch.nil?
|
|
675
|
+
@logger.warn "Received a server-sent channel.close but the channel was not found locally. Ignoring the frame."
|
|
676
|
+
else
|
|
677
|
+
# synchronises on @channel_mutex under the hood
|
|
678
|
+
self.unregister_channel(ch)
|
|
679
|
+
end
|
|
676
680
|
end
|
|
677
681
|
when AMQ::Protocol::Basic::GetEmpty then
|
|
678
682
|
ch = find_channel(ch_number)
|
data/lib/bunny/transport.rb
CHANGED
|
@@ -25,6 +25,30 @@ 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
|
+
"1.0": OpenSSL::SSL::TLS1_VERSION,
|
|
35
|
+
"1.1": OpenSSL::SSL::TLS1_1_VERSION,
|
|
36
|
+
"1.2": OpenSSL::SSL::TLS1_2_VERSION,
|
|
37
|
+
OpenSSL::SSL::TLS1_VERSION => OpenSSL::SSL::TLS1_VERSION,
|
|
38
|
+
OpenSSL::SSL::TLS1_1_VERSION => OpenSSL::SSL::TLS1_1_VERSION,
|
|
39
|
+
OpenSSL::SSL::TLS1_2_VERSION => OpenSSL::SSL::TLS1_2_VERSION
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# older OpenSSL versions won't support for TLS 1.3 and won't
|
|
43
|
+
# have this constant defined.
|
|
44
|
+
if defined?(OpenSSL::SSL::TLS1_3_VERSION)
|
|
45
|
+
TLS_VERSION_ALIASES["1.3"] = OpenSSL::SSL::TLS1_3_VERSION
|
|
46
|
+
TLS_VERSION_ALIASES[:TLSv1_3] = OpenSSL::SSL::TLS1_3_VERSION
|
|
47
|
+
TLS_VERSION_ALIASES[OpenSSL::SSL::TLS1_3_VERSION] = OpenSSL::SSL::TLS1_3_VERSION
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
TLS_VERSION_ALIASES.freeze
|
|
51
|
+
|
|
28
52
|
attr_reader :session, :host, :port, :socket, :connect_timeout, :read_timeout, :write_timeout, :disconnect_timeout
|
|
29
53
|
attr_reader :tls_context, :verify_peer, :tls_ca_certificates, :tls_certificate_path, :tls_key_path
|
|
30
54
|
|
|
@@ -491,7 +515,11 @@ but prone to man-in-the-middle attacks. Please set verify_peer: true in producti
|
|
|
491
515
|
end
|
|
492
516
|
|
|
493
517
|
ssl_version = opts[:tls_protocol] || opts[:ssl_version] || :TLSv1_2
|
|
494
|
-
|
|
518
|
+
if ssl_version
|
|
519
|
+
v = tls_version_constant(ssl_version)
|
|
520
|
+
ctx.min_version = v
|
|
521
|
+
ctx.max_version = v
|
|
522
|
+
end
|
|
495
523
|
|
|
496
524
|
ctx
|
|
497
525
|
end
|
|
@@ -519,6 +547,14 @@ but prone to man-in-the-middle attacks. Please set verify_peer: true in producti
|
|
|
519
547
|
end
|
|
520
548
|
end
|
|
521
549
|
|
|
550
|
+
|
|
551
|
+
def tls_version_constant(value)
|
|
552
|
+
# OpenSSL::SSL::TLS1_3_VERSION and similar constants
|
|
553
|
+
# are just integers, so use the value itself as fallback since
|
|
554
|
+
# there is no class to case switch on
|
|
555
|
+
TLS_VERSION_ALIASES[value] || value
|
|
556
|
+
end
|
|
557
|
+
|
|
522
558
|
def timeout_from(options)
|
|
523
559
|
options[:connect_timeout] || options[:connection_timeout] || options[:timeout] || DEFAULT_CONNECTION_TIMEOUT
|
|
524
560
|
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
|