amqp-client 1.0.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +2 -2
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +29 -12
- data/CHANGELOG.md +21 -0
- data/Gemfile +4 -0
- data/README.md +63 -28
- data/Rakefile +3 -1
- data/amqp-client.gemspec +1 -1
- data/lib/amqp/client/channel.rb +39 -32
- data/lib/amqp/client/connection.rb +107 -64
- data/lib/amqp/client/errors.rb +18 -1
- data/lib/amqp/client/{frames.rb → frame_bytes.rb} +34 -36
- data/lib/amqp/client/message.rb +101 -44
- data/lib/amqp/client/properties.rb +143 -76
- data/lib/amqp/client/queue.rb +15 -21
- data/lib/amqp/client/table.rb +51 -32
- data/lib/amqp/client/version.rb +1 -1
- data/lib/amqp/client.rb +27 -9
- data/sig/amqp-client.rbs +264 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: baa9c2034e80f56aa375a7abb7394109d2f4e84e4a4c04ae8bcb053d299d6dcc
|
4
|
+
data.tar.gz: 7857e1d6ddf96a64df664956da02eac2098fe144a5d2eea1364bd14ba5d41b7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4deaecc1cdce66be71316e3046c5df0832c20a876ad0d3f5884c6e6313ece2d7fad8262f8ee83daad78500ca411648618642eb551c63279e8b84ec727d1f5633
|
7
|
+
data.tar.gz: 4136f5ce5c98610361a673f348fd531a93c34c7989275e7858bfc9694d7368adcbd17beb910fae30cd1fceb29163b7411d4ee0dc235f9c655bfdf960a9de4602
|
data/.github/workflows/main.yml
CHANGED
@@ -19,7 +19,7 @@ jobs:
|
|
19
19
|
strategy:
|
20
20
|
fail-fast: false
|
21
21
|
matrix:
|
22
|
-
ruby: ['2.7', '3.0']
|
22
|
+
ruby: ['2.6', '2.7', '3.0', 'jruby', 'truffleruby']
|
23
23
|
steps:
|
24
24
|
- uses: actions/checkout@v2
|
25
25
|
- name: Set up Ruby
|
@@ -31,5 +31,5 @@ jobs:
|
|
31
31
|
bundle install
|
32
32
|
bundle exec rake
|
33
33
|
env:
|
34
|
+
TESTOPTS: --exclude=/_tls$/
|
34
35
|
AMQP_PORT: ${{ job.services.rabbitmq.ports[5672] }}
|
35
|
-
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,15 +1,27 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2021-
|
3
|
+
# on 2021-10-15 13:44:24 UTC using RuboCop version 1.19.1.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
9
|
+
# Offense count: 1
|
10
|
+
# Cop supports --auto-correct.
|
11
|
+
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
12
|
+
# URISchemes: http, https
|
13
|
+
Layout/LineLength:
|
14
|
+
Max: 132
|
15
|
+
|
16
|
+
# Offense count: 1
|
17
|
+
Lint/RescueException:
|
18
|
+
Exclude:
|
19
|
+
- 'lib/amqp/client/connection.rb'
|
20
|
+
|
21
|
+
# Offense count: 32
|
10
22
|
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
|
11
23
|
Metrics/AbcSize:
|
12
|
-
Max:
|
24
|
+
Max: 175
|
13
25
|
|
14
26
|
# Offense count: 1
|
15
27
|
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
@@ -22,27 +34,32 @@ Metrics/BlockLength:
|
|
22
34
|
Metrics/BlockNesting:
|
23
35
|
Max: 4
|
24
36
|
|
25
|
-
# Offense count:
|
37
|
+
# Offense count: 6
|
26
38
|
# Configuration parameters: CountComments, CountAsOne.
|
27
39
|
Metrics/ClassLength:
|
28
|
-
Max:
|
40
|
+
Max: 497
|
29
41
|
|
30
|
-
# Offense count:
|
42
|
+
# Offense count: 10
|
31
43
|
# Configuration parameters: IgnoredMethods.
|
32
44
|
Metrics/CyclomaticComplexity:
|
33
|
-
Max:
|
45
|
+
Max: 46
|
34
46
|
|
35
|
-
# Offense count:
|
47
|
+
# Offense count: 67
|
36
48
|
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
37
49
|
Metrics/MethodLength:
|
38
|
-
Max:
|
50
|
+
Max: 169
|
39
51
|
|
40
52
|
# Offense count: 2
|
41
53
|
# Configuration parameters: CountComments, CountAsOne.
|
42
54
|
Metrics/ModuleLength:
|
43
|
-
Max:
|
55
|
+
Max: 486
|
56
|
+
|
57
|
+
# Offense count: 1
|
58
|
+
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
59
|
+
Metrics/ParameterLists:
|
60
|
+
Max: 13
|
44
61
|
|
45
|
-
# Offense count:
|
62
|
+
# Offense count: 5
|
46
63
|
# Configuration parameters: IgnoredMethods.
|
47
64
|
Metrics/PerceivedComplexity:
|
48
|
-
Max:
|
65
|
+
Max: 23
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.1.2] - 2021-10-15
|
4
|
+
|
5
|
+
- Added: Support for JRuby and TruffleRuby
|
6
|
+
|
7
|
+
## [1.1.1] - 2021-09-15
|
8
|
+
|
9
|
+
- Added: Examples in the documentation
|
10
|
+
- Added: Faster Properties and Table encoding and decoding
|
11
|
+
|
12
|
+
## [1.1.0] - 2021-09-08
|
13
|
+
|
14
|
+
- Fixed: Due to a race condition publishers could get stuck waiting for publish confirms
|
15
|
+
- Change: Message, ReturnMessage and Properties are now classes and not structs (for performance reasons)
|
16
|
+
- Added: Ruby 2.6 support
|
17
|
+
- Added: RBS signatures in sig/amqp-client.rbs
|
18
|
+
|
19
|
+
## [1.0.2] - 2021-09-07
|
20
|
+
|
21
|
+
- Changed: Raise ConnectionClosed and ChannelClosed correctly (previous always ChannelClosed)
|
22
|
+
- Fixed: Respect Connection#blocked sent by the broker, will block all writes/requests
|
23
|
+
|
3
24
|
## [1.0.1] - 2021-09-06
|
4
25
|
|
5
26
|
- The API is fully documented! https://cloudamqp.github.io/amqp-client.rb/
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,58 +1,67 @@
|
|
1
1
|
# AMQP::Client
|
2
2
|
|
3
|
-
|
3
|
+
A modern AMQP 0-9-1 Ruby client. Very fast (just as fast as the Java client, and >4x than other Ruby clients), fully thread-safe, blocking operations and straight-forward error handling.
|
4
4
|
|
5
|
-
|
5
|
+
It's small, only ~1800 lines of code, and without any dependencies. Other Ruby clients are about 4 times bigger. But without trading functionallity.
|
6
6
|
|
7
|
-
|
7
|
+
It's safe by default, messages are published as persistent, and is waiting for confirmation from the broker. That can of course be disabled if performance is a priority.
|
8
8
|
|
9
|
-
##
|
9
|
+
## Support
|
10
10
|
|
11
|
-
|
11
|
+
The library is fully supported by [CloudAMQP](https://www.cloudamqp.com), the largest RabbitMQ hosting provider in the world. Open [an issue](https://github.com/cloudamqp/amqp-client.rb/issues) or [email our support](mailto:support@cloudamqp.com) if you have problems or questions.
|
12
12
|
|
13
|
-
|
14
|
-
gem 'amqp-client'
|
15
|
-
```
|
16
|
-
|
17
|
-
And then execute:
|
13
|
+
## Documentation
|
18
14
|
|
19
|
-
|
15
|
+
[API reference](https://cloudamqp.github.io/amqp-client.rb/)
|
20
16
|
|
21
|
-
|
17
|
+
## Usage
|
22
18
|
|
23
|
-
|
19
|
+
The client has two APIs.
|
24
20
|
|
25
|
-
|
21
|
+
### Low level API
|
26
22
|
|
27
|
-
|
23
|
+
This API matches the AMQP protocol very well, it can do everything the protocol allows, but requires some knowledge about the protocol, and doesn't handle reconnects.
|
28
24
|
|
29
25
|
```ruby
|
30
26
|
require "amqp-client"
|
31
27
|
|
32
|
-
|
33
|
-
conn =
|
28
|
+
# Opens and establishes a connection
|
29
|
+
conn = AMQP::Client.new("amqp://guest:guest@localhost").connect
|
30
|
+
|
31
|
+
# Open a channel
|
34
32
|
ch = conn.channel
|
33
|
+
|
34
|
+
# Create a temporary queue
|
35
35
|
q = ch.queue_declare
|
36
|
-
|
37
|
-
|
36
|
+
|
37
|
+
# Publish a message to said queue
|
38
|
+
ch.basic_publish_confirm "Hello World!", "", q.queue_name, persistent: true
|
39
|
+
|
40
|
+
# Poll the queue for a message
|
41
|
+
msg = ch.basic_get(q.queue_name)
|
42
|
+
|
43
|
+
# Print the message's body to STDOUT
|
38
44
|
puts msg.body
|
39
45
|
```
|
40
46
|
|
41
|
-
High level API
|
47
|
+
### High level API
|
48
|
+
|
49
|
+
The library provides a high-level API that is a bit easier to get started with, and also handles reconnection automatically.
|
42
50
|
|
43
51
|
```ruby
|
44
|
-
|
45
|
-
|
52
|
+
# Start the client, it will connect and once connected it will reconnect if that connection is lost
|
53
|
+
# Operation pending when the connection is lost will raise an exception (not timeout)
|
54
|
+
amqp = AMQP::Client.new("amqp://localhost").start
|
46
55
|
|
47
56
|
# Declares a durable queue
|
48
|
-
|
57
|
+
myqueue = amqp.queue("myqueue")
|
49
58
|
|
50
59
|
# Bind the queue to any exchange, with any binding key
|
51
|
-
|
60
|
+
myqueue.bind("amq.topic", "my.events.*")
|
52
61
|
|
53
|
-
# The message will be reprocessed if the client loses connection to the
|
62
|
+
# The message will be reprocessed if the client loses connection to the broker
|
54
63
|
# between message arrival and when the message was supposed to be ack'ed.
|
55
|
-
|
64
|
+
myqueue.subscribe(prefetch: 20) do |msg|
|
56
65
|
process(JSON.parse(msg.body))
|
57
66
|
msg.ack
|
58
67
|
rescue
|
@@ -60,13 +69,39 @@ rescue
|
|
60
69
|
end
|
61
70
|
|
62
71
|
# Publish directly to the queue
|
63
|
-
|
72
|
+
myqueue.publish({ foo: "bar" }.to_json, content_type: "application/json")
|
64
73
|
|
65
74
|
# Publish to any exchange
|
66
75
|
amqp.publish("my message", "amq.topic", "topic.foo", headers: { foo: 'bar' })
|
67
76
|
amqp.publish(Zlib.gzip("an event"), "amq.topic", "my.event", content_encoding: 'gzip')
|
68
77
|
```
|
69
78
|
|
79
|
+
## Supported Ruby versions
|
80
|
+
|
81
|
+
All maintained Ruby versions are supported.
|
82
|
+
|
83
|
+
- 3.0
|
84
|
+
- 2.7
|
85
|
+
- 2.6
|
86
|
+
- jruby
|
87
|
+
- truffleruby
|
88
|
+
|
89
|
+
## Installation
|
90
|
+
|
91
|
+
Add this line to your application's Gemfile:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
gem 'amqp-client'
|
95
|
+
```
|
96
|
+
|
97
|
+
And then execute:
|
98
|
+
|
99
|
+
$ bundle install
|
100
|
+
|
101
|
+
Or install it yourself as:
|
102
|
+
|
103
|
+
$ gem install amqp-client
|
104
|
+
|
70
105
|
## Development
|
71
106
|
|
72
107
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -75,7 +110,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
75
110
|
|
76
111
|
## Contributing
|
77
112
|
|
78
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/cloudamqp/amqp-client.rb
|
113
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/cloudamqp/amqp-client.rb](https://github.com/cloudamqp/amqp-client.rb/)
|
79
114
|
|
80
115
|
## License
|
81
116
|
|
data/Rakefile
CHANGED
data/amqp-client.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = "Work in progress"
|
13
13
|
spec.homepage = "https://github.com/cloudamqp/amqp-client.rb"
|
14
14
|
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
16
16
|
|
17
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
18
18
|
spec.metadata["source_code_uri"] = "#{spec.homepage}.git"
|
data/lib/amqp/client/channel.rb
CHANGED
@@ -55,7 +55,7 @@ module AMQP
|
|
55
55
|
return if @closed
|
56
56
|
|
57
57
|
write_bytes FrameBytes.channel_close(@id, reason, code)
|
58
|
-
@closed = [code, reason]
|
58
|
+
@closed = [:channel, code, reason]
|
59
59
|
expect :channel_close_ok
|
60
60
|
@replies.close
|
61
61
|
@basic_gets.close
|
@@ -64,11 +64,12 @@ module AMQP
|
|
64
64
|
nil
|
65
65
|
end
|
66
66
|
|
67
|
-
# Called when channel is closed by
|
67
|
+
# Called when channel is closed by broker
|
68
|
+
# @param level [Symbol] :connection or :channel
|
68
69
|
# @return [nil]
|
69
70
|
# @api private
|
70
|
-
def closed!(code, reason, classid, methodid)
|
71
|
-
@closed = [code, reason, classid, methodid]
|
71
|
+
def closed!(level, code, reason, classid, methodid)
|
72
|
+
@closed = [level, code, reason, classid, methodid]
|
72
73
|
@replies.close
|
73
74
|
@basic_gets.close
|
74
75
|
@unconfirmed_empty.close
|
@@ -77,7 +78,7 @@ module AMQP
|
|
77
78
|
end
|
78
79
|
|
79
80
|
# Handle returned messages in this block. If not set the message will just be logged to STDERR
|
80
|
-
# @yield [ReturnMessage] Messages returned by the
|
81
|
+
# @yield [ReturnMessage] Messages returned by the broker when a publish has failed
|
81
82
|
# @return nil
|
82
83
|
def on_return(&block)
|
83
84
|
@on_return = block
|
@@ -105,7 +106,7 @@ module AMQP
|
|
105
106
|
# Delete an exchange
|
106
107
|
# @param name [String] Name of the exchange
|
107
108
|
# @param if_unused [Boolean] If true raise an exception if queues/exchanges is bound to this exchange
|
108
|
-
# @param no_wait [Boolean] If true don't wait for a
|
109
|
+
# @param no_wait [Boolean] If true don't wait for a broker confirmation
|
109
110
|
# @return [nil]
|
110
111
|
def exchange_delete(name, if_unused: false, no_wait: false)
|
111
112
|
write_bytes FrameBytes.exchange_delete(@id, name, if_unused, no_wait)
|
@@ -174,7 +175,7 @@ module AMQP
|
|
174
175
|
# @param name [String] Name of the queue
|
175
176
|
# @param if_unused [Boolean] Only delete if the queue doesn't have consumers, raises a ChannelClosed error otherwise
|
176
177
|
# @param if_empty [Boolean] Only delete if the queue is empty, raises a ChannelClosed error otherwise
|
177
|
-
# @param no_wait [Boolean] Don't wait for a
|
178
|
+
# @param no_wait [Boolean] Don't wait for a broker confirmation if true
|
178
179
|
# @return [Integer] Number of messages in queue when deleted
|
179
180
|
# @return [nil] If no_wait was set true
|
180
181
|
def queue_delete(name, if_unused: false, if_empty: false, no_wait: false)
|
@@ -197,7 +198,7 @@ module AMQP
|
|
197
198
|
|
198
199
|
# Purge a queue
|
199
200
|
# @param name [String] Name of the queue
|
200
|
-
# @param no_wait [Boolean] Don't wait for a
|
201
|
+
# @param no_wait [Boolean] Don't wait for a broker confirmation if true
|
201
202
|
# @return [nil]
|
202
203
|
def queue_purge(name, no_wait: false)
|
203
204
|
write_bytes FrameBytes.queue_purge(@id, name, no_wait)
|
@@ -214,6 +215,7 @@ module AMQP
|
|
214
215
|
def queue_unbind(name, exchange, binding_key, arguments: {})
|
215
216
|
write_bytes FrameBytes.queue_unbind(@id, name, exchange, binding_key, arguments)
|
216
217
|
expect :queue_unbind_ok
|
218
|
+
nil
|
217
219
|
end
|
218
220
|
|
219
221
|
# @!endgroup
|
@@ -229,7 +231,7 @@ module AMQP
|
|
229
231
|
case (msg = @basic_gets.pop)
|
230
232
|
when Message then msg
|
231
233
|
when :basic_get_empty then nil
|
232
|
-
when nil then raise Error::
|
234
|
+
when nil then raise Error::Closed.new(@id, *@closed)
|
233
235
|
end
|
234
236
|
end
|
235
237
|
|
@@ -238,6 +240,8 @@ module AMQP
|
|
238
240
|
# @param exchange [String] Name of the exchange to publish to
|
239
241
|
# @param routing_key [String] The routing key that the exchange might use to route the message to a queue
|
240
242
|
# @param properties [Properties]
|
243
|
+
# @option properties [Boolean] mandatory The message will be returned if the message can't be routed to a queue
|
244
|
+
# @option properties [Boolean] persistent Same as delivery_mode: 2
|
241
245
|
# @option properties [String] content_type Content type of the message body
|
242
246
|
# @option properties [String] content_encoding Content encoding of the body
|
243
247
|
# @option properties [Hash<String, Object>] headers Custom headers
|
@@ -253,7 +257,7 @@ module AMQP
|
|
253
257
|
# @option properties [String] app_id Can be used to indicates which app that generated the message
|
254
258
|
# @return [nil]
|
255
259
|
def basic_publish(body, exchange, routing_key, **properties)
|
256
|
-
|
260
|
+
body_max = @connection.frame_max - 8
|
257
261
|
id = @id
|
258
262
|
mandatory = properties.delete(:mandatory) || false
|
259
263
|
case properties.delete(:persistent)
|
@@ -261,7 +265,7 @@ module AMQP
|
|
261
265
|
when false then properties[:delivery_mode] = 1
|
262
266
|
end
|
263
267
|
|
264
|
-
if body.bytesize.between?(1,
|
268
|
+
if body.bytesize.between?(1, body_max)
|
265
269
|
write_bytes FrameBytes.basic_publish(id, exchange, routing_key, mandatory),
|
266
270
|
FrameBytes.header(id, body.bytesize, properties),
|
267
271
|
FrameBytes.body(id, body)
|
@@ -273,7 +277,7 @@ module AMQP
|
|
273
277
|
FrameBytes.header(id, body.bytesize, properties)
|
274
278
|
pos = 0
|
275
279
|
while pos < body.bytesize # split body into multiple frame_max frames
|
276
|
-
len = [
|
280
|
+
len = [body_max, body.bytesize - pos].min
|
277
281
|
body_part = body.byteslice(pos, len)
|
278
282
|
write_bytes FrameBytes.body(id, body_part)
|
279
283
|
pos += len
|
@@ -284,7 +288,9 @@ module AMQP
|
|
284
288
|
|
285
289
|
# Publish a message and block until the message has confirmed it has received it
|
286
290
|
# @param (see #basic_publish)
|
291
|
+
# @option (see #basic_publish)
|
287
292
|
# @return [Boolean] True if the message was successfully published
|
293
|
+
# @raise (see #basic_publish)
|
288
294
|
def basic_publish_confirm(body, exchange, routing_key, **properties)
|
289
295
|
confirm_select(no_wait: true)
|
290
296
|
basic_publish(body, exchange, routing_key, **properties)
|
@@ -293,12 +299,13 @@ module AMQP
|
|
293
299
|
|
294
300
|
# Consume messages from a queue
|
295
301
|
# @param queue [String] Name of the queue to subscribe to
|
296
|
-
# @param tag [String] Custom consumer tag, will be auto assigned by the
|
302
|
+
# @param tag [String] Custom consumer tag, will be auto assigned by the broker if empty.
|
303
|
+
# Has to be uniqe among this channel's consumers only
|
297
304
|
# @param no_ack [Boolean] When false messages have to be manually acknowledged (or rejected)
|
298
305
|
# @param exclusive [Boolean] When true only a single consumer can consume from the queue at a time
|
299
|
-
# @param arguments [Hash] Custom arguments
|
306
|
+
# @param arguments [Hash] Custom arguments for the consumer
|
300
307
|
# @param worker_threads [Integer] Number of threads processing messages,
|
301
|
-
# 0 means that the thread calling this method will
|
308
|
+
# 0 means that the thread calling this method will process the messages and thus this method will block
|
302
309
|
# @yield [Message] Delivered message from the queue
|
303
310
|
# @return [Array<(String, Array<Thread>)>] Returns consumer_tag and an array of worker threads
|
304
311
|
# @return [nil] When `worker_threads` is 0 the method will return when the consumer is cancelled
|
@@ -325,7 +332,7 @@ module AMQP
|
|
325
332
|
|
326
333
|
# Cancel/abort/stop a consumer
|
327
334
|
# @param consumer_tag [String] Tag of the consumer to cancel
|
328
|
-
# @param no_wait [Boolean] Will wait for a confirmation from the
|
335
|
+
# @param no_wait [Boolean] Will wait for a confirmation from the broker that the consumer is cancelled
|
329
336
|
# @return [nil]
|
330
337
|
def basic_cancel(consumer_tag, no_wait: false)
|
331
338
|
consumer = @consumers.fetch(consumer_tag)
|
@@ -377,7 +384,7 @@ module AMQP
|
|
377
384
|
|
378
385
|
# Recover all the unacknowledge messages
|
379
386
|
# @param requeue [Boolean] If false the currently unack:ed messages will be deliviered to this consumer again,
|
380
|
-
# if
|
387
|
+
# if true to any consumer
|
381
388
|
# @return [nil]
|
382
389
|
def basic_recover(requeue: false)
|
383
390
|
write_bytes FrameBytes.basic_recover(@id, requeue: requeue)
|
@@ -388,8 +395,8 @@ module AMQP
|
|
388
395
|
# @!endgroup
|
389
396
|
# @!group Confirm
|
390
397
|
|
391
|
-
# Put the channel in confirm mode, each published message will then be confirmed by the
|
392
|
-
# @param no_wait [Boolean] If false the method will block until the
|
398
|
+
# Put the channel in confirm mode, each published message will then be confirmed by the broker
|
399
|
+
# @param no_wait [Boolean] If false the method will block until the broker has confirmed the request
|
393
400
|
# @return [nil]
|
394
401
|
def confirm_select(no_wait: false)
|
395
402
|
return if @confirm
|
@@ -405,14 +412,13 @@ module AMQP
|
|
405
412
|
def wait_for_confirms
|
406
413
|
return true if @unconfirmed.empty?
|
407
414
|
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
end
|
415
|
+
ok = @unconfirmed_empty.pop
|
416
|
+
raise Error::Closed.new(@id, *@closed) if ok.nil?
|
417
|
+
|
418
|
+
ok
|
413
419
|
end
|
414
420
|
|
415
|
-
# Called by Connection when received ack/nack from
|
421
|
+
# Called by Connection when received ack/nack from broker
|
416
422
|
# @api private
|
417
423
|
def confirm(args)
|
418
424
|
ack_or_nack, delivery_tag, multiple = *args
|
@@ -427,9 +433,8 @@ module AMQP
|
|
427
433
|
end
|
428
434
|
return unless @unconfirmed.empty?
|
429
435
|
|
430
|
-
|
431
|
-
|
432
|
-
end
|
436
|
+
ok = ack_or_nack == :ack
|
437
|
+
@unconfirmed_empty.push(ok) until @unconfirmed_empty.num_waiting.zero?
|
433
438
|
end
|
434
439
|
|
435
440
|
# @!endgroup
|
@@ -468,12 +473,12 @@ module AMQP
|
|
468
473
|
|
469
474
|
# @api private
|
470
475
|
def message_returned(reply_code, reply_text, exchange, routing_key)
|
471
|
-
@next_msg = ReturnMessage.new(reply_code, reply_text, exchange, routing_key
|
476
|
+
@next_msg = ReturnMessage.new(reply_code, reply_text, exchange, routing_key)
|
472
477
|
end
|
473
478
|
|
474
479
|
# @api private
|
475
480
|
def message_delivered(consumer_tag, delivery_tag, redelivered, exchange, routing_key)
|
476
|
-
@next_msg = Message.new(self, delivery_tag, exchange, routing_key,
|
481
|
+
@next_msg = Message.new(self, consumer_tag, delivery_tag, exchange, routing_key, redelivered)
|
477
482
|
end
|
478
483
|
|
479
484
|
# @api private
|
@@ -504,6 +509,7 @@ module AMQP
|
|
504
509
|
# @api private
|
505
510
|
def close_consumer(tag)
|
506
511
|
@consumers.fetch(tag).close
|
512
|
+
nil
|
507
513
|
end
|
508
514
|
|
509
515
|
private
|
@@ -522,19 +528,20 @@ module AMQP
|
|
522
528
|
Thread.pass until (consumer = @consumers[next_msg.consumer_tag])
|
523
529
|
consumer.push next_msg
|
524
530
|
end
|
531
|
+
nil
|
525
532
|
ensure
|
526
533
|
@next_msg = @next_body = @next_body_size = nil
|
527
534
|
end
|
528
535
|
|
529
536
|
def write_bytes(*bytes)
|
530
|
-
raise Error::
|
537
|
+
raise Error::Closed.new(@id, *@closed) if @closed
|
531
538
|
|
532
539
|
@connection.write_bytes(*bytes)
|
533
540
|
end
|
534
541
|
|
535
542
|
def expect(expected_frame_type)
|
536
543
|
frame_type, *args = @replies.pop
|
537
|
-
raise Error::
|
544
|
+
raise Error::Closed.new(@id, *@closed) if frame_type.nil?
|
538
545
|
raise Error::UnexpectedFrame.new(expected_frame_type, frame_type) unless frame_type == expected_frame_type
|
539
546
|
|
540
547
|
args
|