amqp-client 1.1.4 → 1.1.6
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/.github/workflows/codeql-analysis.yml +41 -0
- data/.github/workflows/docs.yml +3 -3
- data/.github/workflows/main.yml +43 -32
- data/.github/workflows/release.yml +26 -0
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +3 -1
- data/README.md +25 -9
- data/Rakefile +4 -0
- data/amqp-client.gemspec +1 -7
- data/lib/amqp/client/channel.rb +60 -44
- data/lib/amqp/client/connection.rb +73 -41
- data/lib/amqp/client/version.rb +1 -1
- data/lib/amqp/client.rb +6 -6
- metadata +9 -8
- data/sig/amqp-client.rbs +0 -264
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 10119835607b70ee73dd581f9bef3211a26fc18bb6fb7fa2f6e6bfe913076b16
|
|
4
|
+
data.tar.gz: a30989dab30c2dea294c0310bbfd211a36fa7453d935200c6b7783553f5e816c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2658a0f4e151ab9fd0a56d1096e8d6b191b5e5164e27eadb8dc922651664440149fd1eef7b9d410fbcdf781eba3ef046b141c017b3b5d317b241ec7afa2d8150
|
|
7
|
+
data.tar.gz: 73695493c9f72619279a5552bdea275f6aa781da3da1dadebb788eaff249f68e088b3eb9fc5cc7c3afab1d6df0b44bd83e18ce2aa3605ace83a00035dfd84890
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: "CodeQL"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
# The branches below must be a subset of the branches above
|
|
8
|
+
branches: [ main ]
|
|
9
|
+
schedule:
|
|
10
|
+
- cron: '23 22 * * 2'
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
analyze:
|
|
14
|
+
name: Analyze
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
permissions:
|
|
17
|
+
actions: read
|
|
18
|
+
contents: read
|
|
19
|
+
security-events: write
|
|
20
|
+
|
|
21
|
+
strategy:
|
|
22
|
+
fail-fast: false
|
|
23
|
+
matrix:
|
|
24
|
+
language: [ 'ruby' ]
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- name: Checkout repository
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
# Initializes the CodeQL tools for scanning.
|
|
31
|
+
- name: Initialize CodeQL
|
|
32
|
+
uses: github/codeql-action/init@v3
|
|
33
|
+
with:
|
|
34
|
+
languages: ${{ matrix.language }}
|
|
35
|
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
36
|
+
# By default, queries listed here will override any specified in a config file.
|
|
37
|
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
38
|
+
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
|
39
|
+
|
|
40
|
+
- name: Perform CodeQL Analysis
|
|
41
|
+
uses: github/codeql-action/analyze@v3
|
data/.github/workflows/docs.yml
CHANGED
|
@@ -12,17 +12,17 @@ jobs:
|
|
|
12
12
|
docs:
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
14
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
16
|
- name: Setup Ruby
|
|
17
17
|
uses: ruby/setup-ruby@v1
|
|
18
18
|
with:
|
|
19
|
-
ruby-version:
|
|
19
|
+
ruby-version: ruby
|
|
20
20
|
- name: Install yard
|
|
21
21
|
run: gem install yard
|
|
22
22
|
- name: Generate docs
|
|
23
23
|
run: yard doc
|
|
24
24
|
- name: Deploy docs
|
|
25
|
-
uses: JamesIves/github-pages-deploy-action@
|
|
25
|
+
uses: JamesIves/github-pages-deploy-action@v4.5.0
|
|
26
26
|
with:
|
|
27
27
|
branch: gh-pages
|
|
28
28
|
folder: doc
|
data/.github/workflows/main.yml
CHANGED
|
@@ -1,33 +1,40 @@
|
|
|
1
1
|
name: Ruby
|
|
2
2
|
|
|
3
|
-
on:
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
4
10
|
|
|
5
11
|
jobs:
|
|
6
12
|
tests:
|
|
13
|
+
name: >-
|
|
14
|
+
${{ matrix.ruby }} (sudo: ${{ matrix.sudo }})
|
|
7
15
|
runs-on: ubuntu-latest
|
|
8
|
-
timeout-minutes:
|
|
9
|
-
services:
|
|
10
|
-
rabbitmq:
|
|
11
|
-
image: rabbitmq:latest
|
|
12
|
-
ports:
|
|
13
|
-
- 5672/tcp
|
|
14
|
-
# needed because the rabbitmq container does not provide a healthcheck
|
|
15
|
-
options: >-
|
|
16
|
-
--health-cmd "rabbitmqctl node_health_check"
|
|
17
|
-
--health-interval 10s
|
|
18
|
-
--health-timeout 5s
|
|
19
|
-
--health-retries 5
|
|
16
|
+
timeout-minutes: 10
|
|
20
17
|
strategy:
|
|
21
18
|
fail-fast: false
|
|
22
19
|
matrix:
|
|
23
|
-
|
|
20
|
+
sudo: [true]
|
|
21
|
+
ruby:
|
|
22
|
+
- "2.6"
|
|
23
|
+
- "2.7"
|
|
24
|
+
- "3.0"
|
|
25
|
+
- "3.1"
|
|
26
|
+
- "3.2"
|
|
27
|
+
- "3.3"
|
|
24
28
|
include:
|
|
25
|
-
- { ruby: jruby, allow-failure: true }
|
|
26
|
-
- { ruby: truffleruby, allow-failure: true }
|
|
29
|
+
- { ruby: jruby, allow-failure: true, sudo: false }
|
|
30
|
+
- { ruby: truffleruby, allow-failure: true, sudo: false }
|
|
27
31
|
steps:
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
- name: Install RabbitMQ
|
|
33
|
+
run: sudo apt-get update && sudo apt-get install -y rabbitmq-server
|
|
34
|
+
- name: Verify RabbitMQ started correctly
|
|
35
|
+
run: while true; do sudo rabbitmq-diagnostics status 2>/dev/null && break; echo -n .; sleep 2; done
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
- uses: ruby/setup-ruby@v1
|
|
31
38
|
with:
|
|
32
39
|
bundler-cache: true
|
|
33
40
|
ruby-version: ${{ matrix.ruby }}
|
|
@@ -35,20 +42,25 @@ jobs:
|
|
|
35
42
|
continue-on-error: ${{ matrix.allow-failure || false }}
|
|
36
43
|
run: bundle exec rake
|
|
37
44
|
env:
|
|
38
|
-
|
|
45
|
+
RUN_SUDO_TESTS: ${{ matrix.sudo }}
|
|
46
|
+
|
|
39
47
|
tls:
|
|
40
48
|
runs-on: ubuntu-latest
|
|
41
|
-
timeout-minutes:
|
|
49
|
+
timeout-minutes: 10
|
|
42
50
|
strategy:
|
|
43
51
|
fail-fast: false
|
|
44
52
|
matrix:
|
|
45
|
-
ruby:
|
|
53
|
+
ruby:
|
|
54
|
+
- "ruby" # latest stable release
|
|
55
|
+
- "jruby"
|
|
56
|
+
- "truffleruby"
|
|
46
57
|
steps:
|
|
47
58
|
- name: Install RabbitMQ
|
|
48
59
|
run: sudo apt-get update && sudo apt-get install -y rabbitmq-server
|
|
49
60
|
- name: Stop RabbitMQ
|
|
50
61
|
run: sudo systemctl stop rabbitmq-server
|
|
51
|
-
|
|
62
|
+
- name: Set up Homebrew
|
|
63
|
+
uses: Homebrew/actions/setup-homebrew@master
|
|
52
64
|
- name: Install github.com/FiloSottile/mkcert
|
|
53
65
|
run: brew install mkcert
|
|
54
66
|
- name: Create local CA
|
|
@@ -69,10 +81,8 @@ jobs:
|
|
|
69
81
|
run: sudo systemctl start rabbitmq-server
|
|
70
82
|
- name: Verify RabbitMQ started correctly
|
|
71
83
|
run: while true; do sudo rabbitmq-diagnostics status 2>/dev/null && break; echo -n .; sleep 2; done
|
|
72
|
-
|
|
73
|
-
- uses:
|
|
74
|
-
- name: Set up Ruby
|
|
75
|
-
uses: ruby/setup-ruby@v1
|
|
84
|
+
- uses: actions/checkout@v4
|
|
85
|
+
- uses: ruby/setup-ruby@v1
|
|
76
86
|
with:
|
|
77
87
|
bundler-cache: true
|
|
78
88
|
ruby-version: ${{ matrix.ruby }}
|
|
@@ -80,21 +90,22 @@ jobs:
|
|
|
80
90
|
run: bundle exec rake
|
|
81
91
|
env:
|
|
82
92
|
TESTOPTS: --name=/_tls$/
|
|
93
|
+
|
|
83
94
|
macos:
|
|
84
95
|
runs-on: macos-latest
|
|
85
|
-
timeout-minutes:
|
|
96
|
+
timeout-minutes: 10
|
|
86
97
|
strategy:
|
|
87
98
|
fail-fast: false
|
|
88
99
|
matrix:
|
|
89
|
-
ruby:
|
|
100
|
+
ruby: # enough to test one Ruby on macOS
|
|
101
|
+
- "ruby" # latest stable release
|
|
90
102
|
steps:
|
|
91
103
|
- name: Install RabbitMQ
|
|
92
104
|
run: brew install rabbitmq
|
|
93
105
|
- name: Start RabbitMQ
|
|
94
106
|
run: brew services start rabbitmq
|
|
95
|
-
- uses: actions/checkout@
|
|
96
|
-
-
|
|
97
|
-
uses: ruby/setup-ruby@v1
|
|
107
|
+
- uses: actions/checkout@v4
|
|
108
|
+
- uses: ruby/setup-ruby@v1
|
|
98
109
|
with:
|
|
99
110
|
bundler-cache: true
|
|
100
111
|
ruby-version: ${{ matrix.ruby }}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- v*
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
release:
|
|
11
|
+
if: github.repository == 'cloudamqp/amqp-client.rb'
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write # for trusted publishing
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
bundler-cache: true
|
|
20
|
+
ruby-version: ruby
|
|
21
|
+
- uses: rubygems/configure-rubygems-credentials@v1.0.0
|
|
22
|
+
- run: ruby -v
|
|
23
|
+
# ensure gem can be built and installed, push to rubygems.org
|
|
24
|
+
- run: gem build *.gemspec
|
|
25
|
+
- run: gem install *.gem
|
|
26
|
+
- run: gem push *.gem
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.1.6] - 2024-03-26
|
|
4
|
+
|
|
5
|
+
- Fixed: Channel#wait_for_confirms now waits for all confirms, in a thread safe way
|
|
6
|
+
- Changed: When server sends Connection.blocked the client isn't write blocked anymore, and can continue consume for instance. However, the on_blocked/unblocked callbacks should be used and manually stop publishing as the server otherwise will stop reading from the client socket.
|
|
7
|
+
|
|
8
|
+
## [1.1.5] - 2024-03-15
|
|
9
|
+
|
|
10
|
+
- Fixed: Correctly reference the `UnexpectedFrameEnd` exception
|
|
11
|
+
|
|
3
12
|
## [1.1.4] - 2021-12-27
|
|
4
13
|
|
|
5
14
|
- Fixed: Ruby 3.1.0 compability, StringIO have to be required manually
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -49,6 +49,10 @@ puts msg.body
|
|
|
49
49
|
The library provides a high-level API that is a bit easier to get started with, and also handles reconnection automatically.
|
|
50
50
|
|
|
51
51
|
```ruby
|
|
52
|
+
require "amqp-client"
|
|
53
|
+
require "json"
|
|
54
|
+
require "zlib"
|
|
55
|
+
|
|
52
56
|
# Start the client, it will connect and once connected it will reconnect if that connection is lost
|
|
53
57
|
# Operation pending when the connection is lost will raise an exception (not timeout)
|
|
54
58
|
amqp = AMQP::Client.new("amqp://localhost").start
|
|
@@ -62,9 +66,10 @@ myqueue.bind("amq.topic", "my.events.*")
|
|
|
62
66
|
# The message will be reprocessed if the client loses connection to the broker
|
|
63
67
|
# between message arrival and when the message was supposed to be ack'ed.
|
|
64
68
|
myqueue.subscribe(prefetch: 20) do |msg|
|
|
65
|
-
|
|
69
|
+
puts JSON.parse(msg.body)
|
|
66
70
|
msg.ack
|
|
67
|
-
rescue
|
|
71
|
+
rescue => e
|
|
72
|
+
puts e.full_message
|
|
68
73
|
msg.reject(requeue: false)
|
|
69
74
|
end
|
|
70
75
|
|
|
@@ -76,16 +81,27 @@ amqp.publish("my message", "amq.topic", "topic.foo", headers: { foo: 'bar' })
|
|
|
76
81
|
amqp.publish(Zlib.gzip("an event"), "amq.topic", "my.event", content_encoding: 'gzip')
|
|
77
82
|
```
|
|
78
83
|
|
|
84
|
+
## Benchmark
|
|
85
|
+
|
|
86
|
+
1 byte messages:
|
|
87
|
+
|
|
88
|
+
| Client | Publish rate | Consume rate | Memory usage |
|
|
89
|
+
| ------ | ------------ | ------------ | ------------ |
|
|
90
|
+
| amqp-client.rb | 237.000 msgs/s | 154.000 msgs/s | 23 MB |
|
|
91
|
+
| bunny | 39.000 msgs/s | 44.000 msgs/s | 31 MB |
|
|
92
|
+
|
|
93
|
+
Gem comparison:
|
|
94
|
+
|
|
95
|
+
| Client | Runtime dependencies | [Lines of code](https://github.com/AlDanial/cloc) |
|
|
96
|
+
| --- | --- | --- |
|
|
97
|
+
| amqp-client.rb | 0 | 1876 |
|
|
98
|
+
| bunny | 2 | 4003 |
|
|
99
|
+
|
|
79
100
|
## Supported Ruby versions
|
|
80
101
|
|
|
81
102
|
All maintained Ruby versions are supported.
|
|
82
103
|
|
|
83
|
-
-
|
|
84
|
-
- 3.0
|
|
85
|
-
- 2.7
|
|
86
|
-
- 2.6
|
|
87
|
-
- jruby
|
|
88
|
-
- truffleruby
|
|
104
|
+
See the [CI workflow](https://github.com/cloudamqp/amqp-client.rb/blob/main/.github/workflows/main.yml) for the exact versions.
|
|
89
105
|
|
|
90
106
|
## Installation
|
|
91
107
|
|
|
@@ -107,7 +123,7 @@ Or install it yourself as:
|
|
|
107
123
|
|
|
108
124
|
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.
|
|
109
125
|
|
|
110
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag
|
|
126
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the changelog and version number in `version.rb`, make a commit, and then run `bundle exec rake release:source_control_push`, which will create a git tag for the version, push git commits and the created tag. GitHub Actions will then push the `.gem` file to [rubygems.org](https://rubygems.org/gems/amqp-client).
|
|
111
127
|
|
|
112
128
|
## Contributing
|
|
113
129
|
|
data/Rakefile
CHANGED
data/amqp-client.gemspec
CHANGED
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.email = ["carl@cloudamqp.com"]
|
|
10
10
|
|
|
11
11
|
spec.summary = "AMQP 0-9-1 client"
|
|
12
|
-
spec.description = "
|
|
12
|
+
spec.description = "Modern AMQP 0-9-1 Ruby client"
|
|
13
13
|
spec.homepage = "https://github.com/cloudamqp/amqp-client.rb"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
|
@@ -26,10 +26,4 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
spec.bindir = "exe"
|
|
27
27
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
28
28
|
spec.require_paths = ["lib"]
|
|
29
|
-
|
|
30
|
-
# Uncomment to register a new dependency of your gem
|
|
31
|
-
# spec.add_dependency "example-gem", "~> 1.0"
|
|
32
|
-
|
|
33
|
-
# For more information and examples about making a new gem, checkout our
|
|
34
|
-
# guide at: https://bundler.io/guides/creating_gem.html
|
|
35
29
|
end
|
data/lib/amqp/client/channel.rb
CHANGED
|
@@ -22,8 +22,9 @@ module AMQP
|
|
|
22
22
|
@open = false
|
|
23
23
|
@on_return = nil
|
|
24
24
|
@confirm = nil
|
|
25
|
-
@unconfirmed =
|
|
26
|
-
@
|
|
25
|
+
@unconfirmed = []
|
|
26
|
+
@unconfirmed_lock = Mutex.new
|
|
27
|
+
@unconfirmed_empty = ConditionVariable.new
|
|
27
28
|
@basic_gets = ::Queue.new
|
|
28
29
|
end
|
|
29
30
|
|
|
@@ -60,7 +61,7 @@ module AMQP
|
|
|
60
61
|
expect :channel_close_ok
|
|
61
62
|
@replies.close
|
|
62
63
|
@basic_gets.close
|
|
63
|
-
@unconfirmed_empty.
|
|
64
|
+
@unconfirmed_lock.synchronize { @unconfirmed_empty.broadcast }
|
|
64
65
|
@consumers.each_value(&:close)
|
|
65
66
|
nil
|
|
66
67
|
end
|
|
@@ -73,8 +74,9 @@ module AMQP
|
|
|
73
74
|
@closed = [level, code, reason, classid, methodid]
|
|
74
75
|
@replies.close
|
|
75
76
|
@basic_gets.close
|
|
76
|
-
@unconfirmed_empty.
|
|
77
|
+
@unconfirmed_lock.synchronize { @unconfirmed_empty.broadcast }
|
|
77
78
|
@consumers.each_value(&:close)
|
|
79
|
+
@consumers.each_value(&:clear) # empty the queues too, messages can't be acked anymore
|
|
78
80
|
nil
|
|
79
81
|
end
|
|
80
82
|
|
|
@@ -200,11 +202,12 @@ module AMQP
|
|
|
200
202
|
# Purge a queue
|
|
201
203
|
# @param name [String] Name of the queue
|
|
202
204
|
# @param no_wait [Boolean] Don't wait for a broker confirmation if true
|
|
203
|
-
# @return [
|
|
205
|
+
# @return [Integer] Number of messages in queue when purged
|
|
206
|
+
# @return [nil] If no_wait was set true
|
|
204
207
|
def queue_purge(name, no_wait: false)
|
|
205
208
|
write_bytes FrameBytes.queue_purge(@id, name, no_wait)
|
|
206
|
-
expect :queue_purge_ok unless no_wait
|
|
207
|
-
|
|
209
|
+
message_count, = expect :queue_purge_ok unless no_wait
|
|
210
|
+
message_count
|
|
208
211
|
end
|
|
209
212
|
|
|
210
213
|
# Unbind a queue from an exchange
|
|
@@ -265,12 +268,15 @@ module AMQP
|
|
|
265
268
|
when true then properties[:delivery_mode] = 2
|
|
266
269
|
when false then properties[:delivery_mode] = 1
|
|
267
270
|
end
|
|
268
|
-
|
|
271
|
+
if @confirm
|
|
272
|
+
@unconfirmed_lock.synchronize do
|
|
273
|
+
@unconfirmed.push @confirm += 1
|
|
274
|
+
end
|
|
275
|
+
end
|
|
269
276
|
if body.bytesize.between?(1, body_max)
|
|
270
277
|
write_bytes FrameBytes.basic_publish(id, exchange, routing_key, mandatory),
|
|
271
278
|
FrameBytes.header(id, body.bytesize, properties),
|
|
272
279
|
FrameBytes.body(id, body)
|
|
273
|
-
@unconfirmed.push @confirm += 1 if @confirm
|
|
274
280
|
return
|
|
275
281
|
end
|
|
276
282
|
|
|
@@ -283,7 +289,6 @@ module AMQP
|
|
|
283
289
|
write_bytes FrameBytes.body(id, body_part)
|
|
284
290
|
pos += len
|
|
285
291
|
end
|
|
286
|
-
@unconfirmed.push @confirm += 1 if @confirm
|
|
287
292
|
nil
|
|
288
293
|
end
|
|
289
294
|
|
|
@@ -310,22 +315,16 @@ module AMQP
|
|
|
310
315
|
# @yield [Message] Delivered message from the queue
|
|
311
316
|
# @return [Array<(String, Array<Thread>)>] Returns consumer_tag and an array of worker threads
|
|
312
317
|
# @return [nil] When `worker_threads` is 0 the method will return when the consumer is cancelled
|
|
313
|
-
def basic_consume(queue, tag: "", no_ack: true, exclusive: false, arguments: {}, worker_threads: 1)
|
|
318
|
+
def basic_consume(queue, tag: "", no_ack: true, exclusive: false, arguments: {}, worker_threads: 1, &blk)
|
|
314
319
|
write_bytes FrameBytes.basic_consume(@id, queue, tag, no_ack, exclusive, arguments)
|
|
315
320
|
tag, = expect(:basic_consume_ok)
|
|
316
|
-
|
|
321
|
+
@consumers[tag] = q = ::Queue.new
|
|
317
322
|
if worker_threads.zero?
|
|
318
|
-
|
|
319
|
-
yield (q.pop || break)
|
|
320
|
-
end
|
|
323
|
+
consume_loop(q, tag, &blk)
|
|
321
324
|
nil
|
|
322
325
|
else
|
|
323
326
|
threads = Array.new(worker_threads) do
|
|
324
|
-
Thread.new
|
|
325
|
-
loop do
|
|
326
|
-
yield (q.pop || break)
|
|
327
|
-
end
|
|
328
|
-
end
|
|
327
|
+
Thread.new { consume_loop(q, tag, &blk) }
|
|
329
328
|
end
|
|
330
329
|
[tag, threads]
|
|
331
330
|
end
|
|
@@ -400,42 +399,44 @@ module AMQP
|
|
|
400
399
|
# @param no_wait [Boolean] If false the method will block until the broker has confirmed the request
|
|
401
400
|
# @return [nil]
|
|
402
401
|
def confirm_select(no_wait: false)
|
|
403
|
-
return if @confirm
|
|
402
|
+
return if @confirm # fast path
|
|
404
403
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
404
|
+
@unconfirmed_lock.synchronize do
|
|
405
|
+
# check again in case another thread already did this while we waited for the lock
|
|
406
|
+
return if @confirm
|
|
407
|
+
|
|
408
|
+
write_bytes FrameBytes.confirm_select(@id, no_wait)
|
|
409
|
+
expect :confirm_select_ok unless no_wait
|
|
410
|
+
@confirm = 0
|
|
411
|
+
end
|
|
408
412
|
nil
|
|
409
413
|
end
|
|
410
414
|
|
|
411
415
|
# Block until all publishes messages are confirmed
|
|
412
|
-
# @return
|
|
416
|
+
# @return nil
|
|
413
417
|
def wait_for_confirms
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
418
|
+
@unconfirmed_lock.synchronize do
|
|
419
|
+
until @unconfirmed.empty?
|
|
420
|
+
@unconfirmed_empty.wait(@unconfirmed_lock)
|
|
421
|
+
raise Error::Closed.new(@id, *@closed) if @closed
|
|
422
|
+
end
|
|
423
|
+
end
|
|
420
424
|
end
|
|
421
425
|
|
|
422
426
|
# Called by Connection when received ack/nack from broker
|
|
423
427
|
# @api private
|
|
424
428
|
def confirm(args)
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
429
|
+
_ack_or_nack, delivery_tag, multiple = *args
|
|
430
|
+
@unconfirmed_lock.synchronize do
|
|
431
|
+
case multiple
|
|
432
|
+
when true
|
|
433
|
+
idx = @unconfirmed.index(delivery_tag) || raise("Delivery tag not found")
|
|
434
|
+
@unconfirmed.shift(idx + 1)
|
|
435
|
+
when false
|
|
436
|
+
@unconfirmed.delete(delivery_tag) || raise("Delivery tag not found")
|
|
437
|
+
end
|
|
438
|
+
@unconfirmed_empty.broadcast if @unconfirmed.empty?
|
|
434
439
|
end
|
|
435
|
-
return unless @unconfirmed.empty?
|
|
436
|
-
|
|
437
|
-
ok = ack_or_nack == :ack
|
|
438
|
-
@unconfirmed_empty.push(ok) until @unconfirmed_empty.num_waiting.zero?
|
|
439
440
|
end
|
|
440
441
|
|
|
441
442
|
# @!endgroup
|
|
@@ -547,6 +548,21 @@ module AMQP
|
|
|
547
548
|
|
|
548
549
|
args
|
|
549
550
|
end
|
|
551
|
+
|
|
552
|
+
def consume_loop(queue, tag)
|
|
553
|
+
while (msg = queue.pop)
|
|
554
|
+
begin
|
|
555
|
+
yield msg
|
|
556
|
+
rescue StandardError # cancel the consumer if an uncaught exception is raised
|
|
557
|
+
begin
|
|
558
|
+
close("Unexpected exception in consumer #{tag} thread", 500)
|
|
559
|
+
rescue StandardError # ignore sockets errors while canceling
|
|
560
|
+
nil
|
|
561
|
+
end
|
|
562
|
+
raise # reraise original exception
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
end
|
|
550
566
|
end
|
|
551
567
|
end
|
|
552
568
|
end
|
|
@@ -48,9 +48,22 @@ module AMQP
|
|
|
48
48
|
@replies = ::Queue.new
|
|
49
49
|
@write_lock = Mutex.new
|
|
50
50
|
@blocked = nil
|
|
51
|
+
@on_blocked = ->(reason) { warn "AMQP-Client blocked by broker: #{reason}" }
|
|
52
|
+
@on_unblocked = -> { warn "AMQP-Client unblocked by broker" }
|
|
53
|
+
|
|
51
54
|
Thread.new { read_loop } if read_loop_thread
|
|
52
55
|
end
|
|
53
56
|
|
|
57
|
+
# Indicates that the server is blocking publishes.
|
|
58
|
+
# If the client keeps publishing the server will stop reading from the socket.
|
|
59
|
+
# Use the #on_blocked callback to get notified when the server is resource constrained.
|
|
60
|
+
# @see #on_blocked
|
|
61
|
+
# @see #on_unblocked
|
|
62
|
+
# @return [Bool]
|
|
63
|
+
def blocked?
|
|
64
|
+
!@blocked.nil?
|
|
65
|
+
end
|
|
66
|
+
|
|
54
67
|
# Alias for {#initialize}
|
|
55
68
|
# @see #initialize
|
|
56
69
|
# @deprecated
|
|
@@ -125,20 +138,33 @@ module AMQP
|
|
|
125
138
|
!@closed.nil?
|
|
126
139
|
end
|
|
127
140
|
|
|
141
|
+
# @!group Callbacks
|
|
142
|
+
|
|
143
|
+
# Callback called when client is blocked by the broker
|
|
144
|
+
# @yield [String] reason to why the connection is being blocked
|
|
145
|
+
# @return [nil]
|
|
146
|
+
def on_blocked(&blk)
|
|
147
|
+
@on_blocked = blk
|
|
148
|
+
nil
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Callback called when client is unblocked by the broker
|
|
152
|
+
# @yield
|
|
153
|
+
# @return [nil]
|
|
154
|
+
def on_unblocked(&blk)
|
|
155
|
+
@on_unblocked = blk
|
|
156
|
+
nil
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# @!endgroup
|
|
160
|
+
|
|
128
161
|
# Write byte array(s) directly to the socket (thread-safe)
|
|
129
162
|
# @param bytes [String] One or more byte arrays
|
|
130
163
|
# @return [Integer] number of bytes written
|
|
131
164
|
# @api private
|
|
132
165
|
def write_bytes(*bytes)
|
|
133
|
-
blocked = @blocked
|
|
134
|
-
warn "AMQP-Client blocked by broker: #{blocked}" if blocked
|
|
135
166
|
@write_lock.synchronize do
|
|
136
|
-
|
|
137
|
-
if RUBY_ENGINE == "truffleruby"
|
|
138
|
-
bytes.each { |b| @socket.write b }
|
|
139
|
-
else
|
|
140
|
-
@socket.write(*bytes)
|
|
141
|
-
end
|
|
167
|
+
@socket.write(*bytes)
|
|
142
168
|
end
|
|
143
169
|
rescue *READ_EXCEPTIONS => e
|
|
144
170
|
raise Error::ConnectionClosed.new(*@closed) if @closed
|
|
@@ -166,7 +192,7 @@ module AMQP
|
|
|
166
192
|
|
|
167
193
|
# make sure that the frame end is correct
|
|
168
194
|
frame_end = socket.readchar.ord
|
|
169
|
-
raise UnexpectedFrameEnd, frame_end if frame_end != 206
|
|
195
|
+
raise Error::UnexpectedFrameEnd, frame_end if frame_end != 206
|
|
170
196
|
|
|
171
197
|
# parse the frame, will return false if a close frame was received
|
|
172
198
|
parse_frame(type, channel_id, frame_buffer) || return
|
|
@@ -179,8 +205,12 @@ module AMQP
|
|
|
179
205
|
@closed ||= [400, "unknown"]
|
|
180
206
|
@replies.close
|
|
181
207
|
begin
|
|
182
|
-
@write_lock.
|
|
208
|
+
if @write_lock.owned? # if connection is blocked
|
|
183
209
|
@socket.close
|
|
210
|
+
else
|
|
211
|
+
@write_lock.synchronize do
|
|
212
|
+
@socket.close
|
|
213
|
+
end
|
|
184
214
|
end
|
|
185
215
|
rescue *READ_EXCEPTIONS
|
|
186
216
|
nil
|
|
@@ -192,7 +222,8 @@ module AMQP
|
|
|
192
222
|
READ_EXCEPTIONS = [IOError, OpenSSL::OpenSSLError, SystemCallError,
|
|
193
223
|
RUBY_ENGINE == "jruby" ? java.lang.NullPointerException : nil].compact.freeze
|
|
194
224
|
|
|
195
|
-
def parse_frame(type, channel_id, buf)
|
|
225
|
+
def parse_frame(type, channel_id, buf) # rubocop:disable Metrics/MethodLength
|
|
226
|
+
channel = @channels[channel_id]
|
|
196
227
|
case type
|
|
197
228
|
when 1 # method frame
|
|
198
229
|
class_id, method_id = buf.unpack("S> S>")
|
|
@@ -220,16 +251,16 @@ module AMQP
|
|
|
220
251
|
reason_len = buf.getbyte(4)
|
|
221
252
|
reason = buf.byteslice(5, reason_len).force_encoding("utf-8")
|
|
222
253
|
@blocked = reason
|
|
223
|
-
@
|
|
254
|
+
@on_blocked.call(reason)
|
|
224
255
|
when 61 # connection#unblocked
|
|
225
256
|
@blocked = nil
|
|
226
|
-
@
|
|
257
|
+
@on_unblocked.call
|
|
227
258
|
else raise Error::UnsupportedMethodFrame, class_id, method_id
|
|
228
259
|
end
|
|
229
260
|
when 20 # channel
|
|
230
261
|
case method_id
|
|
231
262
|
when 11 # channel#open-ok
|
|
232
|
-
|
|
263
|
+
channel.reply [:channel_open_ok]
|
|
233
264
|
when 40 # channel#close
|
|
234
265
|
reply_code, reply_text_len = buf.unpack("@4 S> C")
|
|
235
266
|
reply_text = buf.byteslice(7, reply_text_len).force_encoding("utf-8")
|
|
@@ -245,13 +276,13 @@ module AMQP
|
|
|
245
276
|
when 40 # exchange
|
|
246
277
|
case method_id
|
|
247
278
|
when 11 # declare-ok
|
|
248
|
-
|
|
279
|
+
channel.reply [:exchange_declare_ok]
|
|
249
280
|
when 21 # delete-ok
|
|
250
|
-
|
|
281
|
+
channel.reply [:exchange_delete_ok]
|
|
251
282
|
when 31 # bind-ok
|
|
252
|
-
|
|
283
|
+
channel.reply [:exchange_bind_ok]
|
|
253
284
|
when 51 # unbind-ok
|
|
254
|
-
|
|
285
|
+
channel.reply [:exchange_unbind_ok]
|
|
255
286
|
else raise Error::UnsupportedMethodFrame, class_id, method_id
|
|
256
287
|
end
|
|
257
288
|
when 50 # queue
|
|
@@ -260,36 +291,37 @@ module AMQP
|
|
|
260
291
|
queue_name_len = buf.getbyte(4)
|
|
261
292
|
queue_name = buf.byteslice(5, queue_name_len).force_encoding("utf-8")
|
|
262
293
|
message_count, consumer_count = buf.byteslice(5 + queue_name_len, 8).unpack("L> L>")
|
|
263
|
-
|
|
294
|
+
channel.reply [:queue_declare_ok, queue_name, message_count, consumer_count]
|
|
264
295
|
when 21 # bind-ok
|
|
265
|
-
|
|
296
|
+
channel.reply [:queue_bind_ok]
|
|
266
297
|
when 31 # purge-ok
|
|
267
|
-
@
|
|
298
|
+
message_count = buf.unpack1("@4 L>")
|
|
299
|
+
channel.reply [:queue_purge_ok, message_count]
|
|
268
300
|
when 41 # delete-ok
|
|
269
301
|
message_count = buf.unpack1("@4 L>")
|
|
270
|
-
|
|
302
|
+
channel.reply [:queue_delete, message_count]
|
|
271
303
|
when 51 # unbind-ok
|
|
272
|
-
|
|
304
|
+
channel.reply [:queue_unbind_ok]
|
|
273
305
|
else raise Error::UnsupportedMethodFrame.new class_id, method_id
|
|
274
306
|
end
|
|
275
307
|
when 60 # basic
|
|
276
308
|
case method_id
|
|
277
309
|
when 11 # qos-ok
|
|
278
|
-
|
|
310
|
+
channel.reply [:basic_qos_ok]
|
|
279
311
|
when 21 # consume-ok
|
|
280
312
|
tag_len = buf.getbyte(4)
|
|
281
313
|
tag = buf.byteslice(5, tag_len).force_encoding("utf-8")
|
|
282
|
-
|
|
314
|
+
channel.reply [:basic_consume_ok, tag]
|
|
283
315
|
when 30 # cancel
|
|
284
316
|
tag_len = buf.getbyte(4)
|
|
285
317
|
tag = buf.byteslice(5, tag_len).force_encoding("utf-8")
|
|
286
318
|
no_wait = buf.getbyte(5 + tag_len) == 1
|
|
287
|
-
|
|
319
|
+
channel.close_consumer(tag)
|
|
288
320
|
write_bytes FrameBytes.basic_cancel_ok(@id, tag) unless no_wait
|
|
289
321
|
when 31 # cancel-ok
|
|
290
322
|
tag_len = buf.getbyte(4)
|
|
291
323
|
tag = buf.byteslice(5, tag_len).force_encoding("utf-8")
|
|
292
|
-
|
|
324
|
+
channel.reply [:basic_cancel_ok, tag]
|
|
293
325
|
when 50 # return
|
|
294
326
|
reply_code, reply_text_len = buf.unpack("@4 S> C")
|
|
295
327
|
pos = 7
|
|
@@ -302,7 +334,7 @@ module AMQP
|
|
|
302
334
|
routing_key_len = buf.getbyte(pos)
|
|
303
335
|
pos += 1
|
|
304
336
|
routing_key = buf.byteslice(pos, routing_key_len).force_encoding("utf-8")
|
|
305
|
-
|
|
337
|
+
channel.message_returned(reply_code, reply_text, exchange, routing_key)
|
|
306
338
|
when 60 # deliver
|
|
307
339
|
ctag_len = buf.getbyte(4)
|
|
308
340
|
consumer_tag = buf.byteslice(5, ctag_len).force_encoding("utf-8")
|
|
@@ -314,7 +346,7 @@ module AMQP
|
|
|
314
346
|
rk_len = buf.getbyte(pos)
|
|
315
347
|
pos += 1
|
|
316
348
|
routing_key = buf.byteslice(pos, rk_len).force_encoding("utf-8")
|
|
317
|
-
|
|
349
|
+
channel.message_delivered(consumer_tag, delivery_tag, redelivered == 1, exchange, routing_key)
|
|
318
350
|
when 71 # get-ok
|
|
319
351
|
delivery_tag, redelivered, exchange_len = buf.unpack("@4 Q> C C")
|
|
320
352
|
pos = 14
|
|
@@ -325,33 +357,33 @@ module AMQP
|
|
|
325
357
|
routing_key = buf.byteslice(pos, routing_key_len).force_encoding("utf-8")
|
|
326
358
|
# pos += routing_key_len
|
|
327
359
|
# message_count = buf.byteslice(pos, 4).unpack1("L>")
|
|
328
|
-
|
|
360
|
+
channel.message_delivered(nil, delivery_tag, redelivered == 1, exchange, routing_key)
|
|
329
361
|
when 72 # get-empty
|
|
330
|
-
|
|
362
|
+
channel.basic_get_empty
|
|
331
363
|
when 80 # ack
|
|
332
364
|
delivery_tag, multiple = buf.unpack("@4 Q> C")
|
|
333
|
-
|
|
365
|
+
channel.confirm [:ack, delivery_tag, multiple == 1]
|
|
334
366
|
when 111 # recover-ok
|
|
335
|
-
|
|
367
|
+
channel.reply [:basic_recover_ok]
|
|
336
368
|
when 120 # nack
|
|
337
369
|
delivery_tag, multiple, requeue = buf.unpack("@4 Q> C C")
|
|
338
|
-
|
|
370
|
+
channel.confirm [:nack, delivery_tag, multiple == 1, requeue == 1]
|
|
339
371
|
else raise Error::UnsupportedMethodFrame.new class_id, method_id
|
|
340
372
|
end
|
|
341
373
|
when 85 # confirm
|
|
342
374
|
case method_id
|
|
343
375
|
when 11 # select-ok
|
|
344
|
-
|
|
376
|
+
channel.reply [:confirm_select_ok]
|
|
345
377
|
else raise Error::UnsupportedMethodFrame.new class_id, method_id
|
|
346
378
|
end
|
|
347
379
|
when 90 # tx
|
|
348
380
|
case method_id
|
|
349
381
|
when 11 # select-ok
|
|
350
|
-
|
|
382
|
+
channel.reply [:tx_select_ok]
|
|
351
383
|
when 21 # commit-ok
|
|
352
|
-
|
|
384
|
+
channel.reply [:tx_commit_ok]
|
|
353
385
|
when 31 # rollback-ok
|
|
354
|
-
|
|
386
|
+
channel.reply [:tx_rollback_ok]
|
|
355
387
|
else raise Error::UnsupportedMethodFrame.new class_id, method_id
|
|
356
388
|
end
|
|
357
389
|
else raise Error::UnsupportedMethodFrame.new class_id, method_id
|
|
@@ -359,9 +391,9 @@ module AMQP
|
|
|
359
391
|
when 2 # header
|
|
360
392
|
body_size = buf.unpack1("@4 Q>")
|
|
361
393
|
properties = Properties.decode(buf, 12)
|
|
362
|
-
|
|
394
|
+
channel.header_delivered body_size, properties
|
|
363
395
|
when 3 # body
|
|
364
|
-
|
|
396
|
+
channel.body_delivered buf
|
|
365
397
|
else raise Error::UnsupportedFrameType, type
|
|
366
398
|
end
|
|
367
399
|
true
|
|
@@ -419,7 +451,7 @@ module AMQP
|
|
|
419
451
|
|
|
420
452
|
type, channel_id, frame_size = buf.unpack("C S> L>")
|
|
421
453
|
frame_end = buf.getbyte(frame_size + 7)
|
|
422
|
-
raise
|
|
454
|
+
raise Error::UnexpectedFrameEnd, frame_end if frame_end != 206
|
|
423
455
|
|
|
424
456
|
case type
|
|
425
457
|
when 1 # method frame
|
data/lib/amqp/client/version.rb
CHANGED
data/lib/amqp/client.rb
CHANGED
|
@@ -26,7 +26,6 @@ module AMQP
|
|
|
26
26
|
def initialize(uri = "", **options)
|
|
27
27
|
@uri = uri
|
|
28
28
|
@options = options
|
|
29
|
-
|
|
30
29
|
@queues = {}
|
|
31
30
|
@exchanges = {}
|
|
32
31
|
@subscriptions = Set.new
|
|
@@ -172,15 +171,16 @@ module AMQP
|
|
|
172
171
|
|
|
173
172
|
# Consume messages from a queue
|
|
174
173
|
# @param queue [String] Name of the queue to subscribe to
|
|
175
|
-
# @param no_ack [Boolean] When false messages have to be manually acknowledged (or rejected)
|
|
176
|
-
# @param prefetch [Integer] Specify how many messages to prefetch for consumers with no_ack is false
|
|
177
|
-
# @param worker_threads [Integer] Number of threads processing messages
|
|
178
|
-
# 0 means that the thread calling this method will be blocked
|
|
174
|
+
# @param no_ack [Boolean] When false messages have to be manually acknowledged (or rejected) (default: false)
|
|
175
|
+
# @param prefetch [Integer] Specify how many messages to prefetch for consumers with no_ack is false (default: 1)
|
|
176
|
+
# @param worker_threads [Integer] Number of threads processing messages (default: 1)
|
|
179
177
|
# @param arguments [Hash] Custom arguments to the consumer
|
|
180
178
|
# @yield [Message] Delivered message from the queue
|
|
181
179
|
# @return [Array<(String, Array<Thread>)>] Returns consumer_tag and an array of worker threads
|
|
182
|
-
# @return [nil]
|
|
180
|
+
# @return [nil]
|
|
183
181
|
def subscribe(queue, no_ack: false, prefetch: 1, worker_threads: 1, arguments: {}, &blk)
|
|
182
|
+
raise ArgumentError, "worker_threads have to be > 0" if worker_threads <= 0
|
|
183
|
+
|
|
184
184
|
@subscriptions.add? [queue, no_ack, prefetch, worker_threads, arguments, blk]
|
|
185
185
|
|
|
186
186
|
with_connection do |conn|
|
metadata
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: amqp-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carl Hörberg
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-03-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
|
-
description:
|
|
13
|
+
description: Modern AMQP 0-9-1 Ruby client
|
|
14
14
|
email:
|
|
15
15
|
- carl@cloudamqp.com
|
|
16
16
|
executables: []
|
|
17
17
|
extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
|
19
19
|
files:
|
|
20
|
+
- ".github/workflows/codeql-analysis.yml"
|
|
20
21
|
- ".github/workflows/docs.yml"
|
|
21
22
|
- ".github/workflows/main.yml"
|
|
23
|
+
- ".github/workflows/release.yml"
|
|
22
24
|
- ".gitignore"
|
|
23
25
|
- ".rubocop.yml"
|
|
24
26
|
- ".rubocop_todo.yml"
|
|
@@ -43,7 +45,6 @@ files:
|
|
|
43
45
|
- lib/amqp/client/queue.rb
|
|
44
46
|
- lib/amqp/client/table.rb
|
|
45
47
|
- lib/amqp/client/version.rb
|
|
46
|
-
- sig/amqp-client.rbs
|
|
47
48
|
homepage: https://github.com/cloudamqp/amqp-client.rb
|
|
48
49
|
licenses:
|
|
49
50
|
- MIT
|
|
@@ -51,7 +52,7 @@ metadata:
|
|
|
51
52
|
homepage_uri: https://github.com/cloudamqp/amqp-client.rb
|
|
52
53
|
source_code_uri: https://github.com/cloudamqp/amqp-client.rb.git
|
|
53
54
|
changelog_uri: https://github.com/cloudamqp/amqp-client.rb/blob/main/CHANGELOG.md
|
|
54
|
-
post_install_message:
|
|
55
|
+
post_install_message:
|
|
55
56
|
rdoc_options: []
|
|
56
57
|
require_paths:
|
|
57
58
|
- lib
|
|
@@ -66,8 +67,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
66
67
|
- !ruby/object:Gem::Version
|
|
67
68
|
version: '0'
|
|
68
69
|
requirements: []
|
|
69
|
-
rubygems_version: 3.
|
|
70
|
-
signing_key:
|
|
70
|
+
rubygems_version: 3.5.3
|
|
71
|
+
signing_key:
|
|
71
72
|
specification_version: 4
|
|
72
73
|
summary: AMQP 0-9-1 client
|
|
73
74
|
test_files: []
|
data/sig/amqp-client.rbs
DELETED
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
# TypeProf 0.15.3
|
|
2
|
-
|
|
3
|
-
# Classes
|
|
4
|
-
module AMQP
|
|
5
|
-
class Client
|
|
6
|
-
VERSION: String
|
|
7
|
-
@uri: String
|
|
8
|
-
@options: Hash[Symbol, (String | Integer | bool)]
|
|
9
|
-
@queues: Hash[String, Queue]
|
|
10
|
-
@exchanges: Hash[String, Exchange]
|
|
11
|
-
@subscriptions: Set[[String, bool, Integer, Integer, Hash[Symbol, untyped], nil]]
|
|
12
|
-
@connq: Thread::SizedQueue
|
|
13
|
-
@stopped: bool
|
|
14
|
-
|
|
15
|
-
def initialize: (?String uri, **untyped) -> void
|
|
16
|
-
def connect: (?read_loop_thread: bool) -> Connection
|
|
17
|
-
def start: -> Client
|
|
18
|
-
def stop: -> nil
|
|
19
|
-
def queue: (String name, ?durable: bool, ?auto_delete: bool, ?arguments: Hash[Symbol | String, (String | Integer | bool)]) -> Queue
|
|
20
|
-
def exchange: (String name, String `type`, ?durable: bool, ?auto_delete: bool, ?internal: bool, ?arguments: Hash[Symbol | String, untyped]) -> Exchange
|
|
21
|
-
def publish: (String body, String exchange, String routing_key, **untyped) -> bool
|
|
22
|
-
def publish_and_forget: (String body, String exchange, String routing_key, **untyped) -> nil
|
|
23
|
-
def wait_for_confirms: -> bool
|
|
24
|
-
def subscribe: (String queue, ?no_ack: bool, ?prefetch: Integer, ?worker_threads: Integer, ?arguments: Hash[Symbol | String, untyped]) { (Message) -> void } -> [String, Array[Thread]]?
|
|
25
|
-
def bind: (String queue, String exchange, String binding_key, ?arguments: Hash[Symbol | String, untyped]) -> nil
|
|
26
|
-
def unbind: (String queue, String exchange, String binding_key, ?arguments: Hash[Symbol | String, untyped]) -> nil
|
|
27
|
-
def purge: (String queue) -> nil
|
|
28
|
-
def delete_queue: (String name, ?if_unused: bool, ?if_empty: bool) -> Integer?
|
|
29
|
-
def exchange_bind: (String destination, String source, String binding_key, ?arguments: Hash[Symbol | String, untyped]) -> nil
|
|
30
|
-
def exchange_unbind: (String destination, String source, String binding_key, ?arguments: Hash[Symbol | String, untyped]) -> nil
|
|
31
|
-
def delete_exchange: (String name) -> nil
|
|
32
|
-
def with_connection: { (Connection) -> void } -> void
|
|
33
|
-
|
|
34
|
-
module Table
|
|
35
|
-
def self.encode: (Hash[Symbol | String, untyped] hash) -> String
|
|
36
|
-
def self.decode: (String bytes) -> Hash[String, untyped]
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
class Properties
|
|
40
|
-
attr_accessor content_type(): String?
|
|
41
|
-
attr_accessor content_encoding(): String?
|
|
42
|
-
attr_accessor headers(): Hash[String | Symbol, untyped]?
|
|
43
|
-
attr_accessor delivery_mode(): Integer?
|
|
44
|
-
attr_accessor priority(): Integer?
|
|
45
|
-
attr_accessor correlation_id(): String?
|
|
46
|
-
attr_accessor reply_to(): String?
|
|
47
|
-
attr_accessor expiration(): (Integer | String)?
|
|
48
|
-
attr_accessor message_id(): String?
|
|
49
|
-
attr_accessor timestamp(): Time?
|
|
50
|
-
attr_accessor type(): String?
|
|
51
|
-
attr_accessor user_id(): String?
|
|
52
|
-
attr_accessor app_id(): String?
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
module FrameBytes
|
|
56
|
-
def self.connection_start_ok: (String response, Hash[untyped, untyped] properties) -> String
|
|
57
|
-
def self.connection_tune_ok: ((Float | Integer | String)? channel_max, (Float | Integer | String)? frame_max, (Float | Integer | String)? heartbeat) -> String
|
|
58
|
-
def self.connection_open: (String vhost) -> String
|
|
59
|
-
def self.connection_close: (Integer code, String reason) -> String
|
|
60
|
-
def self.connection_close_ok: -> String
|
|
61
|
-
def self.channel_open: (Integer id) -> String
|
|
62
|
-
def self.channel_close: (Integer id, String reason, Integer code) -> String
|
|
63
|
-
def self.channel_close_ok: ((Float | Integer | String)? id) -> String
|
|
64
|
-
def self.exchange_declare: (Integer id, untyped name, untyped `type`, bool passive, bool durable, bool auto_delete, bool internal, Hash[untyped, untyped] arguments) -> String
|
|
65
|
-
def self.exchange_delete: (Integer id, untyped name, bool if_unused, bool no_wait) -> String
|
|
66
|
-
def self.exchange_bind: (Integer id, untyped destination, untyped source, untyped binding_key, bool no_wait, Hash[untyped, untyped] arguments) -> String
|
|
67
|
-
def self.exchange_unbind: (Integer id, untyped destination, untyped source, untyped binding_key, bool no_wait, Hash[untyped, untyped] arguments) -> String
|
|
68
|
-
def self.queue_declare: (Integer id, String name, bool passive, bool durable, bool exclusive, bool auto_delete, Hash[untyped, untyped] arguments) -> String
|
|
69
|
-
def self.queue_delete: (Integer id, untyped name, bool if_unused, bool if_empty, bool no_wait) -> String
|
|
70
|
-
def self.queue_bind: (Integer id, untyped queue, untyped exchange, untyped binding_key, bool no_wait, Hash[untyped, untyped] arguments) -> String
|
|
71
|
-
def self.queue_unbind: (Integer id, untyped queue, untyped exchange, untyped binding_key, Hash[untyped, untyped] arguments) -> String
|
|
72
|
-
def self.queue_purge: (Integer id, untyped queue, bool no_wait) -> String
|
|
73
|
-
def self.basic_get: (Integer id, untyped queue, bool no_ack) -> String
|
|
74
|
-
def self.basic_publish: (Integer id, untyped exchange, untyped routing_key, bool mandatory) -> String
|
|
75
|
-
def self.header: (Integer id, untyped body_size, Hash[(Symbol | String), untyped] properties) -> String
|
|
76
|
-
def self.body: (Integer id, untyped body_part) -> String
|
|
77
|
-
def self.basic_consume: (Integer id, String queue, String? tag, bool? no_ack, bool? exclusive, Hash[untyped, untyped]? arguments) -> String
|
|
78
|
-
def self.basic_cancel: (Integer id, untyped consumer_tag, ?no_wait: bool) -> String
|
|
79
|
-
def self.basic_cancel_ok: (Integer id, String consumer_tag) -> String
|
|
80
|
-
def self.basic_ack: (Integer id, untyped delivery_tag, bool multiple) -> String
|
|
81
|
-
def self.basic_nack: (Integer id, untyped delivery_tag, bool multiple, bool requeue) -> String
|
|
82
|
-
def self.basic_reject: (Integer id, untyped delivery_tag, bool requeue) -> String
|
|
83
|
-
def self.basic_qos: (Integer id, Integer? prefetch_size, Integer? prefetch_count, bool? global) -> String
|
|
84
|
-
def self.basic_recover: (Integer id, untyped requeue) -> String
|
|
85
|
-
def self.confirm_select: (Integer id, bool no_wait) -> String
|
|
86
|
-
def self.tx_select: (Integer id) -> String
|
|
87
|
-
def self.tx_commit: (Integer id) -> String
|
|
88
|
-
def self.tx_rollback: (Integer id) -> String
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
class Message
|
|
92
|
-
attr_reader channel(): Connection::Channel
|
|
93
|
-
attr_reader delivery_tag(): Integer
|
|
94
|
-
attr_reader exchange(): String
|
|
95
|
-
attr_reader routing_key(): String
|
|
96
|
-
attr_reader redelivered(): bool
|
|
97
|
-
attr_reader consumer_tag(): String?
|
|
98
|
-
attr_accessor properties(): Properties
|
|
99
|
-
attr_accessor body(): String
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
class ReturnMessage
|
|
103
|
-
attr_reader reply_code(): Integer
|
|
104
|
-
attr_reader reply_text(): String
|
|
105
|
-
attr_reader exchange(): String
|
|
106
|
-
attr_reader routing_key(): String
|
|
107
|
-
attr_accessor properties(): Properties
|
|
108
|
-
attr_accessor body(): String
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
class Connection
|
|
112
|
-
CLIENT_PROPERTIES: Hash[Symbol | String, untyped]
|
|
113
|
-
@socket: (IO | untyped)
|
|
114
|
-
@channel_max: Integer
|
|
115
|
-
@heartbeat: Integer
|
|
116
|
-
@channels: Hash[Integer, Channel]
|
|
117
|
-
@closed: Array[untyped]?
|
|
118
|
-
@replies: Thread::Queue
|
|
119
|
-
@write_lock: Thread::Mutex
|
|
120
|
-
@blocked: String?
|
|
121
|
-
@id: Integer
|
|
122
|
-
|
|
123
|
-
def initialize: (?String uri, ?read_loop_thread: bool, **untyped) -> void
|
|
124
|
-
def self.connect: (?String uri, ?read_loop_thread: bool, **untyped) -> Connection
|
|
125
|
-
attr_reader frame_max: Integer
|
|
126
|
-
def inspect: -> String
|
|
127
|
-
def channel: (?Integer? id) -> Channel
|
|
128
|
-
def with_channel: { (Channel) -> void } -> void
|
|
129
|
-
def close: (?reason: String, ?code: Integer) -> nil
|
|
130
|
-
def closed?: -> bool
|
|
131
|
-
def write_bytes: (*String bytes) -> Integer
|
|
132
|
-
def read_loop: -> nil
|
|
133
|
-
|
|
134
|
-
private
|
|
135
|
-
def parse_frame: (Integer `type`, Integer channel_id, String buf) -> bool
|
|
136
|
-
def expect: (:close_ok expected_frame_type) -> untyped
|
|
137
|
-
def open_socket: (String host, Integer port, bool tls, Hash[Symbol, untyped] options) -> (IO | untyped)
|
|
138
|
-
def establish: ((IO | untyped) socket, String user, String password, String vhost, Hash[Symbol, untyped] options) -> [Integer, Integer, Integer]
|
|
139
|
-
def enable_tcp_keepalive: ((IO | untyped) socket) -> void
|
|
140
|
-
def port_from_env: -> Integer?
|
|
141
|
-
|
|
142
|
-
class Channel
|
|
143
|
-
@connection: Connection
|
|
144
|
-
@replies: Thread::Queue
|
|
145
|
-
@consumers: Hash[String, Thread::Queue]
|
|
146
|
-
@closed: Array[(:channel | :connection | Integer | String)]?
|
|
147
|
-
@open: bool
|
|
148
|
-
@on_return: nil
|
|
149
|
-
@confirm: Integer?
|
|
150
|
-
@unconfirmed: Thread::Queue
|
|
151
|
-
@unconfirmed_empty: Thread::Queue
|
|
152
|
-
@basic_gets: Thread::Queue
|
|
153
|
-
@next_msg: (Message | ReturnMessage)?
|
|
154
|
-
@next_body: StringIO?
|
|
155
|
-
@next_body_size: (Float | Integer | String)?
|
|
156
|
-
|
|
157
|
-
def initialize: (Connection connection, Integer? id) -> void
|
|
158
|
-
def inspect: -> String
|
|
159
|
-
attr_reader id: Integer?
|
|
160
|
-
def open: -> Channel
|
|
161
|
-
def close: (?reason: String, ?code: Integer) -> nil
|
|
162
|
-
def closed!: (:channel | :connection level, (Float | Integer | String)? code, String reason, (Float | Integer | String)? classid, (Float | Integer | String)? methodid) -> nil
|
|
163
|
-
def on_return: { (ReturnMessage) -> void } -> void
|
|
164
|
-
def exchange_declare: (String name, String `type`, ?passive: bool, ?durable: bool, ?auto_delete: bool, ?internal: bool, ?arguments: Hash[untyped, untyped]) -> nil
|
|
165
|
-
def exchange_delete: (String name, ?if_unused: bool, ?no_wait: bool) -> nil
|
|
166
|
-
def exchange_bind: (String destination, String source, String binding_key, ?arguments: Hash[untyped, untyped]) -> nil
|
|
167
|
-
def exchange_unbind: (String destination, String source, String binding_key, ?arguments: Hash[untyped, untyped]) -> nil
|
|
168
|
-
def queue_declare: (?String name, ?passive: bool, ?durable: bool, ?exclusive: bool, ?auto_delete: bool, ?arguments: Hash[untyped, untyped]) -> QueueOk
|
|
169
|
-
def queue_delete: (String name, ?if_unused: bool, ?if_empty: bool, ?no_wait: bool) -> Integer?
|
|
170
|
-
def queue_bind: (String name, String exchange, String binding_key, ?arguments: Hash[untyped, untyped]) -> nil
|
|
171
|
-
def queue_purge: (String name, ?no_wait: bool) -> nil
|
|
172
|
-
def queue_unbind: (String name, String exchange, String binding_key, ?arguments: Hash[untyped, untyped]) -> nil
|
|
173
|
-
def basic_get: (String queue_name, ?no_ack: bool) -> Message?
|
|
174
|
-
def basic_publish: (String body, String exchange, String routing_key, **untyped) -> nil
|
|
175
|
-
def basic_publish_confirm: (String body, String exchange, String routing_key, **untyped) -> bool
|
|
176
|
-
def basic_consume: (String queue, ?tag: String, ?no_ack: bool?, ?exclusive: bool, ?arguments: Hash[untyped, untyped]?, ?worker_threads: Integer?) { (Message) -> void } -> [String, Array[Thread]]?
|
|
177
|
-
def basic_cancel: (String consumer_tag, ?no_wait: bool) -> nil
|
|
178
|
-
def basic_qos: (Integer prefetch_count, ?prefetch_size: Integer, ?global: bool) -> nil
|
|
179
|
-
def basic_ack: (Integer delivery_tag, ?multiple: bool) -> nil
|
|
180
|
-
def basic_nack: (Integer delivery_tag, ?multiple: bool, ?requeue: bool) -> nil
|
|
181
|
-
def basic_reject: (Integer delivery_tag, ?requeue: bool) -> nil
|
|
182
|
-
def basic_recover: (?requeue: bool) -> nil
|
|
183
|
-
def confirm_select: (?no_wait: bool) -> nil
|
|
184
|
-
def wait_for_confirms: -> bool
|
|
185
|
-
def tx_select: -> nil
|
|
186
|
-
def tx_commit: -> nil
|
|
187
|
-
def tx_rollback: -> nil
|
|
188
|
-
def reply: (Array[untyped] args) -> void
|
|
189
|
-
def confirm: (Array[(:ack | :nack | Integer | bool)] args) -> nil
|
|
190
|
-
def message_returned: ((Float | Integer | String)? reply_code, String reply_text, String exchange, String routing_key) -> ReturnMessage
|
|
191
|
-
def message_delivered: (String? consumer_tag, (Float | Integer | String)? delivery_tag, bool redelivered, String exchange, String routing_key) -> Message
|
|
192
|
-
def basic_get_empty: -> void
|
|
193
|
-
def header_delivered: (Integer body_size, Properties properties) -> void
|
|
194
|
-
def body_delivered: (String body_part) -> void
|
|
195
|
-
def close_consumer: (String tag) -> nil
|
|
196
|
-
|
|
197
|
-
private
|
|
198
|
-
def next_message_finished!: -> void
|
|
199
|
-
def write_bytes: (*String bytes) -> Integer
|
|
200
|
-
def expect: (Symbol expected_frame_type) -> Array[untyped]
|
|
201
|
-
|
|
202
|
-
class QueueOk < Struct[untyped]
|
|
203
|
-
attr_accessor queue_name(): String
|
|
204
|
-
attr_accessor message_count(): Integer
|
|
205
|
-
attr_accessor consumer_count(): Integer
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
class Error < StandardError
|
|
211
|
-
class UnexpectedFrame < Error
|
|
212
|
-
def initialize: (Symbol expected, Symbol actual) -> void
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
class UnexpectedFrameEnd < Error
|
|
216
|
-
def initialize: (untyped actual) -> void
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
class UnsupportedFrameType < Error
|
|
220
|
-
def initialize: (untyped `type`) -> void
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
class UnsupportedMethodFrame < Error
|
|
224
|
-
def initialize: (Integer class_id, Integer method_id) -> void
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
class Closed < Error
|
|
228
|
-
def self.new: (Integer id, (:channel | :connection) level, Integer code, String reason, ?Integer classid, ?Integer methodid) -> (ChannelClosed | ConnectionClosed)
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
class ChannelClosed < Error
|
|
232
|
-
def initialize: (Integer id, Integer code, String reason, ?Integer classid, ?Integer methodid) -> void
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
class ConnectionClosed < Error
|
|
236
|
-
def initialize: (Integer code, String reason, ?Integer classid, ?Integer methodid) -> void
|
|
237
|
-
end
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
class Exchange
|
|
241
|
-
@client: Client
|
|
242
|
-
@name: String
|
|
243
|
-
|
|
244
|
-
def initialize: (Client client, String name) -> void
|
|
245
|
-
def publish: (String body, String routing_key, **untyped) -> Exchange
|
|
246
|
-
def bind: (String exchange, String binding_key, ?arguments: Hash[String | Symbol, untyped]) -> Exchange
|
|
247
|
-
def unbind: (String exchange, String binding_key, ?arguments: Hash[String | Symbol, untyped]) -> Exchange
|
|
248
|
-
def delete: -> nil
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
class Queue
|
|
252
|
-
@client: Client
|
|
253
|
-
@name: String
|
|
254
|
-
|
|
255
|
-
def initialize: (Client client, String name) -> void
|
|
256
|
-
def publish: (String body, **untyped) -> Queue
|
|
257
|
-
def subscribe: (?no_ack: bool, ?prefetch: Integer, ?worker_threads: Integer, ?arguments: Hash[String | Symbol, untyped]) { (Message) -> void } -> Queue
|
|
258
|
-
def bind: (String exchange, String binding_key, ?arguments: Hash[String | Symbol, untyped]) -> Queue
|
|
259
|
-
def unbind: (String exchange, String binding_key, ?arguments: Hash[String | Symbol, untyped]) -> Queue
|
|
260
|
-
def purge: -> Queue
|
|
261
|
-
def delete: -> nil
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
end
|