bunny 2.15.0 → 2.22.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 +56 -39
- data/lib/bunny/channel.rb +89 -13
- data/lib/bunny/consumer.rb +2 -2
- data/lib/bunny/consumer_work_pool.rb +1 -1
- data/lib/bunny/delivery_info.rb +1 -1
- data/lib/bunny/queue.rb +36 -2
- data/lib/bunny/reader_loop.rb +11 -11
- data/lib/bunny/session.rb +71 -25
- data/lib/bunny/transport.rb +49 -12
- data/lib/bunny/version.rb +1 -1
- data/lib/bunny.rb +45 -4
- metadata +29 -228
- data/.github/ISSUE_TEMPLATE.md +0 -18
- data/.gitignore +0 -28
- data/.rspec +0 -1
- data/.travis.yml +0 -33
- data/.yardopts +0 -8
- data/CONTRIBUTING.md +0 -132
- data/ChangeLog.md +0 -2084
- data/Gemfile +0 -55
- data/LICENSE +0 -21
- data/Rakefile +0 -54
- 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/bunny.gemspec +0 -34
- data/docker/Dockerfile +0 -24
- data/docker/apt/preferences.d/erlang +0 -3
- data/docker/apt/sources.list.d/bintray.rabbitmq.list +0 -2
- data/docker/docker-entrypoint.sh +0 -26
- data/docker/rabbitmq.conf +0 -29
- data/docker-compose.yml +0 -28
- 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_republishing.rb +0 -109
- data/examples/connection/automatic_recovery_with_server_named_queues.rb +0 -35
- data/examples/connection/channel_level_exception.rb +0 -27
- 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/consumers/high_and_low_priority.rb +0 -50
- 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 -30
- 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 -22
- data/examples/guides/getting_started/weathr.rb +0 -49
- data/examples/guides/queues/one_off_consumer.rb +0 -25
- data/examples/guides/queues/redeliveries.rb +0 -81
- data/profiling/basic_publish/with_4K_messages.rb +0 -33
- data/repl +0 -3
- 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 -349
- 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 -563
- 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 -262
- 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/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/tls/ca_certificate.pem +0 -29
- data/spec/tls/ca_key.pem +0 -52
- data/spec/tls/client_certificate.pem +0 -29
- data/spec/tls/client_key.pem +0 -51
- data/spec/tls/generate-server-cert.sh +0 -8
- data/spec/tls/server-openssl.cnf +0 -10
- data/spec/tls/server.csr +0 -16
- data/spec/tls/server_certificate.pem +0 -29
- data/spec/tls/server_key.pem +0 -51
- 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: 2edd88411f92dbdbb1d06b334006e446d5b3e3fb165f3baae3745bd066cf9651
|
4
|
+
data.tar.gz: 437032f606bb6f77fee02e65706e615f8a52c0e05467bbe257f1796fcedd624c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 698398dc76ca4e3dd11e3c5dc6b078998f23895bd3d975b01e1329c08c8ff0835cb9691d0108f0f6e13aaa769b870b258ff5e1de1958321be4804ca99b30a0be
|
7
|
+
data.tar.gz: 2a1fdcc61d683a991d07f601a986c5bc04d40cdd7155a1833dc7dba46be014c23d36612c505531b2f2adfe08ed057d6a493cbf5df368318205ffaf88659a88fb
|
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?
|
@@ -43,12 +43,17 @@ Specific examples:
|
|
43
43
|
Web applications that display that information in the real time.
|
44
44
|
|
45
45
|
|
46
|
-
|
47
46
|
## Supported Ruby Versions
|
48
47
|
|
49
48
|
Modern Bunny versions support
|
50
49
|
|
51
|
-
* 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
|
52
57
|
|
53
58
|
Bunny works sufficiently well on JRuby but there are known
|
54
59
|
JRuby bugs in versions prior to JRuby 9000 that cause high CPU burn. JRuby users should
|
@@ -59,8 +64,7 @@ Bunny `1.7.x` was the last version to support CRuby 1.9.3 and 1.8.7
|
|
59
64
|
|
60
65
|
## Supported RabbitMQ Versions
|
61
66
|
|
62
|
-
Bunny
|
63
|
-
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).
|
64
68
|
|
65
69
|
|
66
70
|
## Change Log
|
@@ -70,11 +74,8 @@ a stable public API.
|
|
70
74
|
|
71
75
|
Change logs per release series:
|
72
76
|
|
73
|
-
* [
|
74
|
-
* [2.
|
75
|
-
* [2.13.x](https://github.com/ruby-amqp/bunny/blob/2.13.x-stable/ChangeLog.md)
|
76
|
-
* [2.12.x](https://github.com/ruby-amqp/bunny/blob/2.12.x-stable/ChangeLog.md)
|
77
|
-
* [2.11.x](https://github.com/ruby-amqp/bunny/blob/2.11.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)
|
78
79
|
|
79
80
|
|
80
81
|
|
@@ -84,20 +85,20 @@ Change logs per release series:
|
|
84
85
|
|
85
86
|
[![Gem Version](https://badge.fury.io/rb/bunny.svg)](http://badge.fury.io/rb/bunny)
|
86
87
|
|
87
|
-
###
|
88
|
+
### Bundler Dependency
|
88
89
|
|
89
|
-
To
|
90
|
+
To use Bunny in a project managed with Bundler:
|
90
91
|
|
91
|
-
```
|
92
|
-
gem
|
92
|
+
``` ruby
|
93
|
+
gem "bunny", ">= 2.19.0"
|
93
94
|
```
|
94
95
|
|
95
|
-
###
|
96
|
+
### With Rubygems
|
96
97
|
|
97
|
-
To
|
98
|
+
To install Bunny with RubyGems:
|
98
99
|
|
99
|
-
```
|
100
|
-
gem
|
100
|
+
```
|
101
|
+
gem install bunny
|
101
102
|
```
|
102
103
|
|
103
104
|
|
@@ -106,7 +107,7 @@ gem "bunny", ">= 2.14.1"
|
|
106
107
|
Below is a small snippet that demonstrates how to publish
|
107
108
|
and synchronously consume ("pull API") messages with Bunny.
|
108
109
|
|
109
|
-
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).
|
110
111
|
|
111
112
|
``` ruby
|
112
113
|
require "bunny"
|
@@ -117,20 +118,31 @@ conn.start
|
|
117
118
|
|
118
119
|
# open a channel
|
119
120
|
ch = conn.create_channel
|
121
|
+
ch.confirm_select
|
120
122
|
|
121
123
|
# declare a queue
|
122
124
|
q = ch.queue("test1")
|
125
|
+
q.subscribe(manual_ack: true) do |delivery_info, metadata, payload|
|
126
|
+
puts "This is the message: #{payload}"
|
127
|
+
# acknowledge the delivery so that RabbitMQ can mark it for deletion
|
128
|
+
ch.ack(delivery_info.delivery_tag)
|
129
|
+
end
|
123
130
|
|
124
131
|
# publish a message to the default exchange which then gets routed to this queue
|
125
132
|
q.publish("Hello, everybody!")
|
126
133
|
|
127
|
-
#
|
128
|
-
|
134
|
+
# await confirmations from RabbitMQ, see
|
135
|
+
# https://www.rabbitmq.com/publishers.html#data-safety for details
|
136
|
+
ch.wait_for_confirms
|
129
137
|
|
130
|
-
|
138
|
+
# give the above consumer some time consume the delivery and print out the message
|
139
|
+
sleep 1
|
131
140
|
|
141
|
+
puts "Done"
|
142
|
+
|
143
|
+
ch.close
|
132
144
|
# close the connection
|
133
|
-
conn.
|
145
|
+
conn.close
|
134
146
|
```
|
135
147
|
|
136
148
|
|
@@ -142,17 +154,29 @@ For a 15 minute tutorial using more practical examples, see [Getting Started wit
|
|
142
154
|
|
143
155
|
### Guides
|
144
156
|
|
145
|
-
|
157
|
+
Bunny documentation guides are [under `docs/guides` in this repository](https://github.com/ruby-amqp/bunny/tree/main/docs/guides):
|
146
158
|
|
147
|
-
* [Queues and Consumers](
|
148
|
-
* [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)
|
149
161
|
* [AMQP 0.9.1 Model Explained](http://www.rabbitmq.com/tutorials/amqp-concepts.html)
|
150
|
-
* [Connecting to RabbitMQ](
|
151
|
-
* [Error Handling and Recovery](
|
152
|
-
* [TLS/SSL Support](
|
153
|
-
* [Bindings](
|
154
|
-
* [Using RabbitMQ Extensions with Bunny](
|
155
|
-
* [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)
|
168
|
+
|
169
|
+
Some highly relevant RabbitMQ documentation guides:
|
170
|
+
|
171
|
+
* [Connections](https://www.rabbitmq.com/connections.html)
|
172
|
+
* [Channels](https://www.rabbitmq.com/channels.html)
|
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))
|
176
|
+
* [Publishers](https://www.rabbitmq.com/publishers.html)
|
177
|
+
* [Consumers](https://www.rabbitmq.com/consumers.html)
|
178
|
+
* Data safety: publisher and consumer [Confirmations](https://www.rabbitmq.com/confirms.html)
|
179
|
+
* [Production Checklist](https://www.rabbitmq.com/production-checklist.html)
|
156
180
|
|
157
181
|
### API Reference
|
158
182
|
|
@@ -176,13 +200,6 @@ mailing list. Feel free to ask any questions that you may have.
|
|
176
200
|
[![Build Status](https://travis-ci.org/ruby-amqp/bunny.svg)](https://travis-ci.org/ruby-amqp/bunny/)
|
177
201
|
|
178
202
|
|
179
|
-
### News & Announcements on Twitter
|
180
|
-
|
181
|
-
To subscribe for announcements of releases, important changes and so on, please follow [@rubyamqp](https://twitter.com/#!/rubyamqp) on Twitter.
|
182
|
-
|
183
|
-
More detailed announcements can be found in the [RabbitMQ Ruby clients blog](http://blog.rubyrabbitmq.info).
|
184
|
-
|
185
|
-
|
186
203
|
### Reporting Issues
|
187
204
|
|
188
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
|
@@ -374,7 +378,7 @@ module Bunny
|
|
374
378
|
# @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
|
375
379
|
# @api public
|
376
380
|
def default_exchange
|
377
|
-
Exchange.default(self)
|
381
|
+
@default_exchange ||= Exchange.default(self)
|
378
382
|
end
|
379
383
|
|
380
384
|
# Declares a headers exchange or looks it up in the cache of previously
|
@@ -392,7 +396,7 @@ module Bunny
|
|
392
396
|
# @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
|
393
397
|
# @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
394
398
|
def exchange(name, opts = {})
|
395
|
-
Exchange.new(self, opts.fetch(:type, :direct), name, opts)
|
399
|
+
find_exchange(name) || Exchange.new(self, opts.fetch(:type, :direct), name, opts)
|
396
400
|
end
|
397
401
|
|
398
402
|
# @endgroup
|
@@ -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
|
#
|
@@ -1156,7 +1227,7 @@ module Bunny
|
|
1156
1227
|
|
1157
1228
|
# @group Exchange operations (exchange.*)
|
1158
1229
|
|
1159
|
-
# Declares a exchange using
|
1230
|
+
# Declares a exchange using exchange.declare AMQP 0.9.1 method.
|
1160
1231
|
#
|
1161
1232
|
# @param [String] name The name of the exchange. Note that LF and CR characters
|
1162
1233
|
# will be stripped from the value.
|
@@ -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 + 1 : 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
|
@@ -70,7 +70,7 @@ module Bunny
|
|
70
70
|
return if !(wait_for_workers && @shutdown_timeout && was_running)
|
71
71
|
|
72
72
|
@shutdown_mutex.synchronize do
|
73
|
-
@shutdown_conditional.wait(@shutdown_mutex, @shutdown_timeout)
|
73
|
+
@shutdown_conditional.wait(@shutdown_mutex, @shutdown_timeout) if busy?
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
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/reader_loop.rb
CHANGED
@@ -9,17 +9,17 @@ module Bunny
|
|
9
9
|
# @private
|
10
10
|
class ReaderLoop
|
11
11
|
|
12
|
-
def initialize(transport, session,
|
13
|
-
@transport
|
14
|
-
@session
|
15
|
-
@
|
16
|
-
@logger
|
12
|
+
def initialize(transport, session, session_error_handler)
|
13
|
+
@transport = transport
|
14
|
+
@session = session
|
15
|
+
@session_error_handler = session_error_handler
|
16
|
+
@logger = @session.logger
|
17
17
|
|
18
|
-
@mutex
|
18
|
+
@mutex = Mutex.new
|
19
19
|
|
20
|
-
@stopping
|
21
|
-
@stopped
|
22
|
-
@network_is_down
|
20
|
+
@stopping = false
|
21
|
+
@stopped = false
|
22
|
+
@network_is_down = false
|
23
23
|
end
|
24
24
|
|
25
25
|
|
@@ -47,7 +47,7 @@ module Bunny
|
|
47
47
|
@session.handle_network_failure(e)
|
48
48
|
else
|
49
49
|
log_exception(e)
|
50
|
-
@
|
50
|
+
@session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
|
51
51
|
end
|
52
52
|
rescue ShutdownSignal => _
|
53
53
|
@mutex.synchronize { @stopping = true }
|
@@ -58,7 +58,7 @@ module Bunny
|
|
58
58
|
log_exception(e)
|
59
59
|
|
60
60
|
@network_is_down = true
|
61
|
-
@
|
61
|
+
@session_error_handler.raise(Bunny::NetworkFailure.new("caught an unexpected exception in the network loop: #{e.message}", e))
|
62
62
|
end
|
63
63
|
rescue Errno::EBADF => _ebadf
|
64
64
|
break if terminate?
|