amq-protocol 2.7.0 → 2.8.0
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/ChangeLog.md +21 -1
- data/lib/amq/bit_set.rb +1 -1
- data/lib/amq/int_allocator.rb +2 -3
- data/lib/amq/protocol/client.rb +1 -3
- data/lib/amq/protocol/frame.rb +7 -7
- data/lib/amq/protocol/table_value_decoder.rb +1 -1
- data/lib/amq/protocol/table_value_encoder.rb +1 -1
- data/lib/amq/protocol/version.rb +1 -1
- data/lib/amq/uri.rb +8 -4
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7cd695fb0f7f7cc8c9d80109f349fdba92c500b5b8eea4ff6ea2c5e6dfdddd8d
|
|
4
|
+
data.tar.gz: 929be34e6f1bd9c2f84fded2933e9f3775286e19babbabac45ce0ccab1b3c38d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 990e85acbfc80b8dbfa1be036705afdef1f96fdae2b1c8270ff00c972483925361d9dbb7807309fca6a0db55c3d795f8da34d3255f153ff463cda2d12ceed918
|
|
7
|
+
data.tar.gz: 62f8b49269c978f162a21aced9eb22702ae676e28589da94f66b1560083c66878584a1999fa0611f4be1f205a402539b228f0d165107dc930d7a7112801cb8aa
|
data/ChangeLog.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## Changes between 2.8.0 and 2.9.0 (unreleased)
|
|
2
|
+
|
|
3
|
+
No changes yet.
|
|
4
|
+
|
|
5
|
+
## Changes between 2.7.0 and 2.8.0 (Apr 25, 2026)
|
|
6
|
+
|
|
7
|
+
### Performance Improvements in Frame Decoding and Encoding
|
|
8
|
+
|
|
9
|
+
Replacing `x == nil` with `x.nil?` in the frame layer hot path yields a
|
|
10
|
+
consistent **+15–18% throughput improvement** in `Frame.decode_header`
|
|
11
|
+
(called on every received frame) and **+12–14%** in `HeartbeatFrame.encode`,
|
|
12
|
+
across Ruby 3.3, 3.4, and 4.0.
|
|
13
|
+
|
|
14
|
+
See benchmarks/BENCHMARKS.md for instructions on how to reproduce these numbers on your machine.
|
|
15
|
+
|
|
16
|
+
Contributed by @eglitobias.
|
|
17
|
+
|
|
18
|
+
GitHub issue: [#86](https://github.com/ruby-amqp/amq-protocol/pull/86)
|
|
19
|
+
|
|
20
|
+
|
|
1
21
|
## Changes between 2.6.0 and 2.7.0 (Mar 31, 2026)
|
|
2
22
|
|
|
3
23
|
### Channel.Close Predicates Now Return True Boolean
|
|
@@ -42,7 +62,7 @@ Optimized encoding and decoding hot paths:
|
|
|
42
62
|
* Switched to `unpack1` instead of `unpack().first` throughout
|
|
43
63
|
* Use `byteslice` instead of `slice` for binary string operations
|
|
44
64
|
* Use `getbyte` for single byte access (4x faster than alternatives)
|
|
45
|
-
* Adopted `frozen_string_literal` pragma
|
|
65
|
+
* Adopted the `frozen_string_literal` pragma
|
|
46
66
|
|
|
47
67
|
The improvements on Ruby 3.4 are very meaningful:
|
|
48
68
|
|
data/lib/amq/bit_set.rb
CHANGED
|
@@ -113,7 +113,7 @@ module AMQ
|
|
|
113
113
|
|
|
114
114
|
def check_range(i)
|
|
115
115
|
if i < 0 || i >= @nbits
|
|
116
|
-
raise IndexError
|
|
116
|
+
raise IndexError, "Cannot access bit #{i} from a BitSet with #{@nbits} bits"
|
|
117
117
|
end
|
|
118
118
|
end # check_range
|
|
119
119
|
end # BitSet
|
data/lib/amq/int_allocator.rb
CHANGED
|
@@ -26,13 +26,12 @@ module AMQ
|
|
|
26
26
|
# @param [Integer] hi Upper boundary of the integer range available for allocation
|
|
27
27
|
# @raise [ArgumentError] if upper boundary is not greater than the lower one
|
|
28
28
|
def initialize(lo, hi)
|
|
29
|
-
raise ArgumentError
|
|
29
|
+
raise ArgumentError, "upper boundary must be greater than the lower one (given: hi = #{hi}, lo = #{lo})" unless hi > lo
|
|
30
30
|
|
|
31
31
|
@hi = hi
|
|
32
32
|
@lo = lo
|
|
33
33
|
|
|
34
34
|
@number_of_bits = hi - lo
|
|
35
|
-
@range = Range.new(1, @number_of_bits)
|
|
36
35
|
@free_set = BitSet.new(@number_of_bits)
|
|
37
36
|
end # initialize(hi, lo)
|
|
38
37
|
|
|
@@ -47,7 +46,7 @@ module AMQ
|
|
|
47
46
|
|
|
48
47
|
if n = @free_set.next_clear_bit
|
|
49
48
|
|
|
50
|
-
if n < @hi - 1
|
|
49
|
+
if n < @hi - 1
|
|
51
50
|
@free_set.set(n)
|
|
52
51
|
n + 1
|
|
53
52
|
else
|
data/lib/amq/protocol/client.rb
CHANGED
|
@@ -173,9 +173,7 @@ module AMQ
|
|
|
173
173
|
limit = frame_size - 8
|
|
174
174
|
return [BodyFrame.new(body, channel)] if body.bytesize < limit
|
|
175
175
|
|
|
176
|
-
|
|
177
|
-
# and we need bytes. MK.
|
|
178
|
-
body.force_encoding("ASCII-8BIT") if RUBY_VERSION.to_f >= 1.9 && body.encoding != Encoding::BINARY
|
|
176
|
+
body.force_encoding("ASCII-8BIT") if body.encoding != Encoding::BINARY
|
|
179
177
|
|
|
180
178
|
array = Array.new
|
|
181
179
|
while body && !body.empty?
|
data/lib/amq/protocol/frame.rb
CHANGED
|
@@ -23,8 +23,8 @@ module AMQ
|
|
|
23
23
|
|
|
24
24
|
# The channel number is 0 for all frames which are global to the connection and 1-65535 for frames that refer to specific channels.
|
|
25
25
|
def self.encode_to_array(type, payload, channel)
|
|
26
|
-
raise RuntimeError
|
|
27
|
-
raise RuntimeError
|
|
26
|
+
raise RuntimeError, "Channel has to be 0 or an integer in range 1..65535 but was #{channel.inspect}" unless CHANNEL_RANGE.include?(channel)
|
|
27
|
+
raise RuntimeError, "Payload can't be nil" if payload.nil?
|
|
28
28
|
components = []
|
|
29
29
|
components << [find_type(type), channel, payload.bytesize].pack(PACK_CHAR_UINT16_UINT32)
|
|
30
30
|
components << encoded_payload(payload)
|
|
@@ -47,13 +47,13 @@ module AMQ
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def self.find_type(type)
|
|
50
|
-
type_id =
|
|
51
|
-
raise FrameTypeError
|
|
50
|
+
type_id = type.is_a?(Symbol) ? TYPES[type] : type
|
|
51
|
+
raise FrameTypeError, TYPES_OPTIONS if type.nil? || !TYPES_REVERSE.key?(type_id)
|
|
52
52
|
type_id
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def self.decode(*)
|
|
56
|
-
raise NotImplementedError
|
|
56
|
+
raise NotImplementedError, <<-EOF
|
|
57
57
|
You are supposed to redefine this method, because it's dependent on used IO adapter.
|
|
58
58
|
|
|
59
59
|
This functionality is part of the https://github.com/ruby-amqp/amq-client library.
|
|
@@ -62,12 +62,12 @@ This functionality is part of the https://github.com/ruby-amqp/amq-client librar
|
|
|
62
62
|
|
|
63
63
|
# Optimized header decode using unpack1 for single values where appropriate
|
|
64
64
|
def self.decode_header(header)
|
|
65
|
-
raise EmptyResponseError if header
|
|
65
|
+
raise EmptyResponseError if header.nil? || header.empty?
|
|
66
66
|
|
|
67
67
|
# Use unpack for multiple values - this is the optimal approach
|
|
68
68
|
type_id, channel, size = header.unpack(PACK_CHAR_UINT16_UINT32)
|
|
69
69
|
type = TYPES_REVERSE[type_id]
|
|
70
|
-
raise FrameTypeError
|
|
70
|
+
raise FrameTypeError, TYPES_OPTIONS unless type
|
|
71
71
|
[type, channel, size]
|
|
72
72
|
end
|
|
73
73
|
|
|
@@ -83,7 +83,7 @@ module AMQ
|
|
|
83
83
|
v, offset = decode_array(data, offset)
|
|
84
84
|
v
|
|
85
85
|
else
|
|
86
|
-
raise ArgumentError
|
|
86
|
+
raise ArgumentError, "unsupported type in a table value: #{type.inspect}, do not know how to decode!"
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
ary << i
|
|
@@ -72,7 +72,7 @@ module AMQ
|
|
|
72
72
|
accumulator << [0, value.to_i].pack(PACK_UCHAR_UINT32)
|
|
73
73
|
end
|
|
74
74
|
else
|
|
75
|
-
raise ArgumentError
|
|
75
|
+
raise ArgumentError, "Unsupported value #{value.inspect} of type #{value.class.name}"
|
|
76
76
|
end # if
|
|
77
77
|
end # case
|
|
78
78
|
|
data/lib/amq/protocol/version.rb
CHANGED
data/lib/amq/uri.rb
CHANGED
|
@@ -31,7 +31,9 @@ module AMQ
|
|
|
31
31
|
|
|
32
32
|
def self.parse(connection_string)
|
|
33
33
|
uri = ::URI.parse(connection_string)
|
|
34
|
-
|
|
34
|
+
unless %w{amqp amqps}.include?(uri.scheme)
|
|
35
|
+
raise ArgumentError, "Connection URI must use amqp or amqps schema (example: amqp://bus.megacorp.internal:5766), learn more at http://bit.ly/ks8MXK"
|
|
36
|
+
end
|
|
35
37
|
|
|
36
38
|
opts = DEFAULTS.dup
|
|
37
39
|
|
|
@@ -42,7 +44,9 @@ module AMQ
|
|
|
42
44
|
opts[:port] = uri.port || AMQP_DEFAULT_PORTS[uri.scheme]
|
|
43
45
|
opts[:ssl] = uri.scheme.to_s.downcase =~ /amqps/i # TODO: rename to tls
|
|
44
46
|
if uri.path =~ %r{^/(.*)}
|
|
45
|
-
|
|
47
|
+
if $1.index('/')
|
|
48
|
+
raise ArgumentError, "#{uri} has multiple-segment path; please percent-encode any slashes in the vhost name (e.g. /production => %2Fproduction). Learn more at http://bit.ly/amqp-gem-and-connection-uris"
|
|
49
|
+
end
|
|
46
50
|
opts[:vhost] = ::CGI::unescape($1)
|
|
47
51
|
end
|
|
48
52
|
|
|
@@ -63,7 +67,7 @@ module AMQ
|
|
|
63
67
|
|
|
64
68
|
%w(cacertfile certfile keyfile).each do |tls_option|
|
|
65
69
|
if query_params[tls_option] && uri.scheme == "amqp"
|
|
66
|
-
raise ArgumentError
|
|
70
|
+
raise ArgumentError, "The option '#{tls_option}' can only be used in URIs that use amqps schema"
|
|
67
71
|
else
|
|
68
72
|
opts[tls_option.to_sym] = query_params[tls_option]
|
|
69
73
|
end
|
|
@@ -71,7 +75,7 @@ module AMQ
|
|
|
71
75
|
|
|
72
76
|
%w(verify fail_if_no_peer_cert).each do |tls_option|
|
|
73
77
|
if query_params[tls_option] && uri.scheme == "amqp"
|
|
74
|
-
raise ArgumentError
|
|
78
|
+
raise ArgumentError, "The option '#{tls_option}' can only be used in URIs that use amqps schema"
|
|
75
79
|
else
|
|
76
80
|
opts[tls_option.to_sym] = as_boolean(query_params[tls_option])
|
|
77
81
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: amq-protocol
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jakub Stastny
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
- Mark Abramov
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date:
|
|
13
|
+
date: 2026-04-26 00:00:00.000000000 Z
|
|
14
14
|
dependencies: []
|
|
15
15
|
description: |2
|
|
16
16
|
amq-protocol is an AMQP 0.9.1 serialization library for Ruby. It is not a
|
|
@@ -43,7 +43,7 @@ files:
|
|
|
43
43
|
- lib/amq/protocol/version.rb
|
|
44
44
|
- lib/amq/settings.rb
|
|
45
45
|
- lib/amq/uri.rb
|
|
46
|
-
homepage:
|
|
46
|
+
homepage: https://github.com/ruby-amqp/amq-protocol
|
|
47
47
|
licenses:
|
|
48
48
|
- MIT
|
|
49
49
|
metadata: {}
|
|
@@ -54,14 +54,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
54
54
|
requirements:
|
|
55
55
|
- - ">="
|
|
56
56
|
- !ruby/object:Gem::Version
|
|
57
|
-
version: '
|
|
57
|
+
version: '3.0'
|
|
58
58
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
59
|
requirements:
|
|
60
60
|
- - ">="
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
62
|
version: '0'
|
|
63
63
|
requirements: []
|
|
64
|
-
rubygems_version: 3.6.
|
|
64
|
+
rubygems_version: 3.6.2
|
|
65
65
|
specification_version: 4
|
|
66
66
|
summary: AMQP 0.9.1 encoding & decoding library.
|
|
67
67
|
test_files: []
|