amqp-client 1.0.2 → 1.1.3
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 +22 -0
- data/Gemfile +4 -0
- data/README.md +62 -27
- data/Rakefile +3 -1
- data/amqp-client.gemspec +1 -1
- data/lib/amqp/client/channel.rb +11 -10
- data/lib/amqp/client/connection.rb +93 -56
- 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/table.rb +51 -32
- data/lib/amqp/client/version.rb +1 -1
- data/lib/amqp/client.rb +19 -7
- 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: 191cd8053858a46d350a6c89db378058c9c602bde3eadc95ee4ae79b149fb0cf
|
4
|
+
data.tar.gz: c322ca75508f8a9566170fa473b562dfe4b4989dc6b1e2baa68408612fe47692
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c47bba0271dbd49b603127ac8749bfd85468ea7b0faa97d857eca585cde012094ace144b339a71d24fc4c90dace83f5e562669ae040ddb1eedd54b24eb6a876
|
7
|
+
data.tar.gz: 3ecb4641c83020063186fa1ac4413e6e42ae33ecb013eae3d2dcadfa1c30a3943ddf6320561ccb63917376ac23ac908c87f2d7e64abd7508c69c9f1030460e8e
|
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,27 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.1.3] - 2021-11-04
|
4
|
+
|
5
|
+
- Fixed: Reraise SystemcallError in connect so that reconnect works
|
6
|
+
- Fixed: Keepalive support in OS X
|
7
|
+
- Added: Make keepalive settings configurable (eg. amqp://?keepalive=60:10:3)
|
8
|
+
|
9
|
+
## [1.1.2] - 2021-10-15
|
10
|
+
|
11
|
+
- Added: Support for JRuby and TruffleRuby
|
12
|
+
|
13
|
+
## [1.1.1] - 2021-09-15
|
14
|
+
|
15
|
+
- Added: Examples in the documentation
|
16
|
+
- Added: Faster Properties and Table encoding and decoding
|
17
|
+
|
18
|
+
## [1.1.0] - 2021-09-08
|
19
|
+
|
20
|
+
- Fixed: Due to a race condition publishers could get stuck waiting for publish confirms
|
21
|
+
- Change: Message, ReturnMessage and Properties are now classes and not structs (for performance reasons)
|
22
|
+
- Added: Ruby 2.6 support
|
23
|
+
- Added: RBS signatures in sig/amqp-client.rbs
|
24
|
+
|
3
25
|
## [1.0.2] - 2021-09-07
|
4
26
|
|
5
27
|
- Changed: Raise ConnectionClosed and ChannelClosed correctly (previous always ChannelClosed)
|
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
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
@@ -215,6 +215,7 @@ module AMQP
|
|
215
215
|
def queue_unbind(name, exchange, binding_key, arguments: {})
|
216
216
|
write_bytes FrameBytes.queue_unbind(@id, name, exchange, binding_key, arguments)
|
217
217
|
expect :queue_unbind_ok
|
218
|
+
nil
|
218
219
|
end
|
219
220
|
|
220
221
|
# @!endgroup
|
@@ -411,11 +412,10 @@ module AMQP
|
|
411
412
|
def wait_for_confirms
|
412
413
|
return true if @unconfirmed.empty?
|
413
414
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
end
|
415
|
+
ok = @unconfirmed_empty.pop
|
416
|
+
raise Error::Closed.new(@id, *@closed) if ok.nil?
|
417
|
+
|
418
|
+
ok
|
419
419
|
end
|
420
420
|
|
421
421
|
# Called by Connection when received ack/nack from broker
|
@@ -433,9 +433,8 @@ module AMQP
|
|
433
433
|
end
|
434
434
|
return unless @unconfirmed.empty?
|
435
435
|
|
436
|
-
|
437
|
-
|
438
|
-
end
|
436
|
+
ok = ack_or_nack == :ack
|
437
|
+
@unconfirmed_empty.push(ok) until @unconfirmed_empty.num_waiting.zero?
|
439
438
|
end
|
440
439
|
|
441
440
|
# @!endgroup
|
@@ -474,12 +473,12 @@ module AMQP
|
|
474
473
|
|
475
474
|
# @api private
|
476
475
|
def message_returned(reply_code, reply_text, exchange, routing_key)
|
477
|
-
@next_msg = ReturnMessage.new(reply_code, reply_text, exchange, routing_key
|
476
|
+
@next_msg = ReturnMessage.new(reply_code, reply_text, exchange, routing_key)
|
478
477
|
end
|
479
478
|
|
480
479
|
# @api private
|
481
480
|
def message_delivered(consumer_tag, delivery_tag, redelivered, exchange, routing_key)
|
482
|
-
@next_msg = Message.new(self, delivery_tag, exchange, routing_key,
|
481
|
+
@next_msg = Message.new(self, consumer_tag, delivery_tag, exchange, routing_key, redelivered)
|
483
482
|
end
|
484
483
|
|
485
484
|
# @api private
|
@@ -510,6 +509,7 @@ module AMQP
|
|
510
509
|
# @api private
|
511
510
|
def close_consumer(tag)
|
512
511
|
@consumers.fetch(tag).close
|
512
|
+
nil
|
513
513
|
end
|
514
514
|
|
515
515
|
private
|
@@ -528,6 +528,7 @@ module AMQP
|
|
528
528
|
Thread.pass until (consumer = @consumers[next_msg.consumer_tag])
|
529
529
|
consumer.push next_msg
|
530
530
|
end
|
531
|
+
nil
|
531
532
|
ensure
|
532
533
|
@next_msg = @next_body = @next_body_size = nil
|
533
534
|
end
|