amqp-client 1.1.0 → 1.1.1
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 +5 -0
- data/README.md +7 -3
- data/lib/amqp/client/connection.rb +2 -2
- data/lib/amqp/client/{frames.rb → frame_bytes.rb} +1 -1
- data/lib/amqp/client/properties.rb +69 -35
- data/lib/amqp/client/table.rb +46 -25
- data/lib/amqp/client/version.rb +1 -1
- data/lib/amqp/client.rb +15 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e248898d176ad9c3d785226ed37c0335052ef701ee16a16bff483089be65dd8
|
4
|
+
data.tar.gz: 89b58399edb11b30b05db86e9e4b0a617438e3ed52e63b3e76ae3a4c8cb361fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4500bec819ea9de9546f001eed682ac040ea3c2f93904dabb24afdbbda966d3352d8b1e33687a82c482ce835e7d650172dd906d9ef4ec2efc17f1dea31947314
|
7
|
+
data.tar.gz: 62ea49dc2782122146dd2613cd51b1c4132b3eef9d48c5573e9369b0af96042018f104a84cfe2aa2f173cf6d10f5ca3e427baa3ef61faed7029cd7328148a762
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.1.1] - 2021-09-15
|
4
|
+
|
5
|
+
- Added: Examples in the documentation
|
6
|
+
- Added: Faster Properties and Table encoding and decoding
|
7
|
+
|
3
8
|
## [1.1.0] - 2021-09-08
|
4
9
|
|
5
10
|
- Fixed: Due to a race condition publishers could get stuck waiting for publish confirms
|
data/README.md
CHANGED
@@ -2,6 +2,10 @@
|
|
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
|
+
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
|
+
|
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
|
+
|
5
9
|
## Support
|
6
10
|
|
7
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.
|
@@ -31,10 +35,10 @@ ch = conn.channel
|
|
31
35
|
q = ch.queue_declare
|
32
36
|
|
33
37
|
# Publish a message to said queue
|
34
|
-
ch.
|
38
|
+
ch.basic_publish_confirm "Hello World!", "", q.queue_name, persistent: true
|
35
39
|
|
36
40
|
# Poll the queue for a message
|
37
|
-
msg = ch.basic_get
|
41
|
+
msg = ch.basic_get(q.queue_name)
|
38
42
|
|
39
43
|
# Print the message's body to STDOUT
|
40
44
|
puts msg.body
|
@@ -104,7 +108,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
104
108
|
|
105
109
|
## Contributing
|
106
110
|
|
107
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/cloudamqp/amqp-client.rb
|
111
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/cloudamqp/amqp-client.rb](https://github.com/cloudamqp/amqp-client.rb/)
|
108
112
|
|
109
113
|
## License
|
110
114
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "socket"
|
4
4
|
require "uri"
|
5
5
|
require "openssl"
|
6
|
-
require_relative "./
|
6
|
+
require_relative "./frame_bytes"
|
7
7
|
require_relative "./channel"
|
8
8
|
require_relative "./errors"
|
9
9
|
|
@@ -350,7 +350,7 @@ module AMQP
|
|
350
350
|
end
|
351
351
|
when 2 # header
|
352
352
|
body_size = buf.unpack1("@4 Q>")
|
353
|
-
properties = Properties.decode(buf
|
353
|
+
properties = Properties.decode(buf, 12)
|
354
354
|
@channels[channel_id].header_delivered body_size, properties
|
355
355
|
when 3 # body
|
356
356
|
@channels[channel_id].body_delivered buf
|
@@ -23,56 +23,90 @@ module AMQP
|
|
23
23
|
@app_id = app_id
|
24
24
|
end
|
25
25
|
|
26
|
+
# Properties as a Hash
|
27
|
+
# @return [Hash] Properties
|
28
|
+
def to_h
|
29
|
+
{
|
30
|
+
content_type: content_type,
|
31
|
+
content_encoding: content_encoding,
|
32
|
+
headers: headers,
|
33
|
+
delivery_mode: delivery_mode,
|
34
|
+
priority: priority,
|
35
|
+
correlation_id: correlation_id,
|
36
|
+
reply_to: reply_to,
|
37
|
+
expiration: expiration,
|
38
|
+
message_id: message_id,
|
39
|
+
timestamp: timestamp,
|
40
|
+
type: type,
|
41
|
+
user_id: user_id,
|
42
|
+
app_id: app_id
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
alias to_hash to_h
|
47
|
+
|
48
|
+
# Returns true if two Property objects holds the same information
|
49
|
+
# @return [Boolean]
|
50
|
+
def ==(other)
|
51
|
+
return false unless other.is_a? self.class
|
52
|
+
|
53
|
+
instance_variables.all? { |v| instance_variable_get(v) == other.instance_variable_get(v) }
|
54
|
+
end
|
55
|
+
|
26
56
|
# Content type of the message body
|
27
57
|
# @return [String, nil]
|
28
58
|
attr_accessor :content_type
|
29
59
|
# Content encoding of the body
|
30
60
|
# @return [String, nil]
|
31
61
|
attr_accessor :content_encoding
|
32
|
-
#
|
62
|
+
# Headers, for applications and header exchange routing
|
33
63
|
# @return [Hash<String, Object>, nil]
|
34
64
|
attr_accessor :headers
|
35
|
-
#
|
36
|
-
# @
|
65
|
+
# Message persistent level
|
66
|
+
# @note The exchange and queue have to durable as well for the message to be persistent
|
67
|
+
# @return [1] Transient message
|
68
|
+
# @return [2] Persistent message
|
69
|
+
# @return [nil] Not specified (implicitly transient)
|
37
70
|
attr_accessor :delivery_mode
|
38
71
|
# A priority of the message (between 0 and 255)
|
39
72
|
# @return [Integer, nil]
|
40
73
|
attr_accessor :priority
|
41
|
-
#
|
42
|
-
# @return [
|
74
|
+
# Message correlation id, commonly used to correlate RPC requests and responses
|
75
|
+
# @return [String, nil]
|
43
76
|
attr_accessor :correlation_id
|
44
77
|
# Queue to reply RPC responses to
|
45
78
|
# @return [String, nil]
|
46
79
|
attr_accessor :reply_to
|
47
80
|
# Number of seconds the message will stay in the queue
|
48
|
-
# @return [
|
49
|
-
# @return [String]
|
50
|
-
# @return [nil]
|
81
|
+
# @return [String, nil]
|
51
82
|
attr_accessor :expiration
|
83
|
+
# Application message identifier
|
52
84
|
# @return [String, nil]
|
53
85
|
attr_accessor :message_id
|
54
|
-
#
|
86
|
+
# Message timestamp, often indicates when the message was originally generated
|
55
87
|
# @return [Date, nil]
|
56
88
|
attr_accessor :timestamp
|
57
|
-
#
|
89
|
+
# Message type name
|
58
90
|
# @return [String, nil]
|
59
91
|
attr_accessor :type
|
60
|
-
#
|
92
|
+
# The user that published the message
|
61
93
|
# @return [String, nil]
|
62
94
|
attr_accessor :user_id
|
63
|
-
#
|
95
|
+
# Name of application that generated the message
|
64
96
|
# @return [String, nil]
|
65
97
|
attr_accessor :app_id
|
66
98
|
|
67
99
|
# Encode properties into a byte array
|
100
|
+
# @param properties [Hash]
|
68
101
|
# @return [String] byte array
|
69
|
-
def encode
|
102
|
+
def self.encode(properties)
|
103
|
+
return "\x00\x00" if properties.empty?
|
104
|
+
|
70
105
|
flags = 0
|
71
106
|
arr = [flags]
|
72
|
-
fmt =
|
73
|
-
fmt.pos = 2
|
107
|
+
fmt = String.new("S>", capacity: 37)
|
74
108
|
|
75
|
-
if content_type
|
109
|
+
if (content_type = properties[:content_type])
|
76
110
|
content_type.is_a?(String) || raise(ArgumentError, "content_type must be a string")
|
77
111
|
|
78
112
|
flags |= (1 << 15)
|
@@ -80,7 +114,7 @@ module AMQP
|
|
80
114
|
fmt << "Ca*"
|
81
115
|
end
|
82
116
|
|
83
|
-
if content_encoding
|
117
|
+
if (content_encoding = properties[:content_encoding])
|
84
118
|
content_encoding.is_a?(String) || raise(ArgumentError, "content_encoding must be a string")
|
85
119
|
|
86
120
|
flags |= (1 << 14)
|
@@ -88,7 +122,7 @@ module AMQP
|
|
88
122
|
fmt << "Ca*"
|
89
123
|
end
|
90
124
|
|
91
|
-
if headers
|
125
|
+
if (headers = properties[:headers])
|
92
126
|
headers.is_a?(Hash) || raise(ArgumentError, "headers must be a hash")
|
93
127
|
|
94
128
|
flags |= (1 << 13)
|
@@ -97,31 +131,31 @@ module AMQP
|
|
97
131
|
fmt << "L>a*"
|
98
132
|
end
|
99
133
|
|
100
|
-
if delivery_mode
|
134
|
+
if (delivery_mode = properties[:delivery_mode])
|
101
135
|
delivery_mode.is_a?(Integer) || raise(ArgumentError, "delivery_mode must be an int")
|
102
|
-
delivery_mode.between?(0, 2) || raise(ArgumentError, "delivery_mode must be be between 0 and 2")
|
103
136
|
|
104
137
|
flags |= (1 << 12)
|
105
138
|
arr << delivery_mode
|
106
139
|
fmt << "C"
|
107
140
|
end
|
108
141
|
|
109
|
-
if priority
|
142
|
+
if (priority = properties[:priority])
|
110
143
|
priority.is_a?(Integer) || raise(ArgumentError, "priority must be an int")
|
144
|
+
|
111
145
|
flags |= (1 << 11)
|
112
146
|
arr << priority
|
113
147
|
fmt << "C"
|
114
148
|
end
|
115
149
|
|
116
|
-
if correlation_id
|
117
|
-
|
150
|
+
if (correlation_id = properties[:correlation_id])
|
151
|
+
correlation_id.is_a?(String) || raise(ArgumentError, "correlation_id must be a string")
|
118
152
|
|
119
153
|
flags |= (1 << 10)
|
120
154
|
arr << correlation_id.bytesize << correlation_id
|
121
155
|
fmt << "Ca*"
|
122
156
|
end
|
123
157
|
|
124
|
-
if reply_to
|
158
|
+
if (reply_to = properties[:reply_to])
|
125
159
|
reply_to.is_a?(String) || raise(ArgumentError, "reply_to must be a string")
|
126
160
|
|
127
161
|
flags |= (1 << 9)
|
@@ -129,8 +163,8 @@ module AMQP
|
|
129
163
|
fmt << "Ca*"
|
130
164
|
end
|
131
165
|
|
132
|
-
if expiration
|
133
|
-
|
166
|
+
if (expiration = properties[:expiration])
|
167
|
+
expiration = expiration.to_s if expiration.is_a?(Integer)
|
134
168
|
expiration.is_a?(String) || raise(ArgumentError, "expiration must be a string or integer")
|
135
169
|
|
136
170
|
flags |= (1 << 8)
|
@@ -138,7 +172,7 @@ module AMQP
|
|
138
172
|
fmt << "Ca*"
|
139
173
|
end
|
140
174
|
|
141
|
-
if message_id
|
175
|
+
if (message_id = properties[:message_id])
|
142
176
|
message_id.is_a?(String) || raise(ArgumentError, "message_id must be a string")
|
143
177
|
|
144
178
|
flags |= (1 << 7)
|
@@ -146,7 +180,7 @@ module AMQP
|
|
146
180
|
fmt << "Ca*"
|
147
181
|
end
|
148
182
|
|
149
|
-
if timestamp
|
183
|
+
if (timestamp = properties[:timestamp])
|
150
184
|
timestamp.is_a?(Integer) || timestamp.is_a?(Time) || raise(ArgumentError, "timestamp must be an Integer or a Time")
|
151
185
|
|
152
186
|
flags |= (1 << 6)
|
@@ -154,7 +188,7 @@ module AMQP
|
|
154
188
|
fmt << "Q>"
|
155
189
|
end
|
156
190
|
|
157
|
-
if type
|
191
|
+
if (type = properties[:type])
|
158
192
|
type.is_a?(String) || raise(ArgumentError, "type must be a string")
|
159
193
|
|
160
194
|
flags |= (1 << 5)
|
@@ -162,7 +196,7 @@ module AMQP
|
|
162
196
|
fmt << "Ca*"
|
163
197
|
end
|
164
198
|
|
165
|
-
if user_id
|
199
|
+
if (user_id = properties[:user_id])
|
166
200
|
user_id.is_a?(String) || raise(ArgumentError, "user_id must be a string")
|
167
201
|
|
168
202
|
flags |= (1 << 4)
|
@@ -170,7 +204,7 @@ module AMQP
|
|
170
204
|
fmt << "Ca*"
|
171
205
|
end
|
172
206
|
|
173
|
-
if app_id
|
207
|
+
if (app_id = properties[:app_id])
|
174
208
|
app_id.is_a?(String) || raise(ArgumentError, "app_id must be a string")
|
175
209
|
|
176
210
|
flags |= (1 << 3)
|
@@ -179,15 +213,15 @@ module AMQP
|
|
179
213
|
end
|
180
214
|
|
181
215
|
arr[0] = flags
|
182
|
-
arr.pack(fmt
|
216
|
+
arr.pack(fmt)
|
183
217
|
end
|
184
218
|
|
185
219
|
# Decode a byte array
|
186
220
|
# @return [Properties]
|
187
|
-
def self.decode(bytes)
|
221
|
+
def self.decode(bytes, pos = 0)
|
188
222
|
p = new
|
189
|
-
flags = bytes.unpack1("S>")
|
190
|
-
pos
|
223
|
+
flags = bytes.byteslice(pos, 2).unpack1("S>")
|
224
|
+
pos += 2
|
191
225
|
if (flags & 0x8000).positive?
|
192
226
|
len = bytes.getbyte(pos)
|
193
227
|
pos += 1
|
data/lib/amqp/client/table.rb
CHANGED
@@ -6,15 +6,20 @@ module AMQP
|
|
6
6
|
# @api private
|
7
7
|
module Table
|
8
8
|
# Encodes a hash into a byte array
|
9
|
+
# @param hash [Hash]
|
9
10
|
# @return [String] Byte array
|
10
11
|
def self.encode(hash)
|
11
|
-
|
12
|
-
|
12
|
+
return "" if hash.empty?
|
13
|
+
|
14
|
+
arr = []
|
15
|
+
fmt = String.new
|
16
|
+
hash.each do |k, value|
|
13
17
|
key = k.to_s
|
14
|
-
|
15
|
-
|
18
|
+
arr.push(key.bytesize, key)
|
19
|
+
fmt << "Ca*"
|
20
|
+
encode_field(value, arr, fmt)
|
16
21
|
end
|
17
|
-
|
22
|
+
arr.pack(fmt)
|
18
23
|
end
|
19
24
|
|
20
25
|
# Decodes an AMQP table into a hash
|
@@ -27,8 +32,7 @@ module AMQP
|
|
27
32
|
pos += 1
|
28
33
|
key = bytes.byteslice(pos, key_len).force_encoding("utf-8")
|
29
34
|
pos += key_len
|
30
|
-
|
31
|
-
len, value = decode_field(rest)
|
35
|
+
len, value = decode_field(bytes, pos)
|
32
36
|
pos += len + 1
|
33
37
|
hash[key] = value
|
34
38
|
end
|
@@ -36,43 +40,58 @@ module AMQP
|
|
36
40
|
end
|
37
41
|
|
38
42
|
# Encoding a single value in a table
|
43
|
+
# @return [nil]
|
39
44
|
# @api private
|
40
|
-
def self.encode_field(value)
|
45
|
+
def self.encode_field(value, arr, fmt)
|
41
46
|
case value
|
42
47
|
when Integer
|
43
48
|
if value > 2**31
|
44
|
-
|
49
|
+
arr.push("l", value)
|
50
|
+
fmt << "aq>"
|
45
51
|
else
|
46
|
-
|
52
|
+
arr.push("I", value)
|
53
|
+
fmt << "al>"
|
47
54
|
end
|
48
55
|
when Float
|
49
|
-
|
56
|
+
arr.push("d", value)
|
57
|
+
fmt << "aG"
|
50
58
|
when String
|
51
|
-
|
59
|
+
arr.push("S", value.bytesize, value)
|
60
|
+
fmt << "aL>a*"
|
52
61
|
when Time
|
53
|
-
|
62
|
+
arr.push("T", value.to_i)
|
63
|
+
fmt << "aQ>"
|
54
64
|
when Array
|
55
|
-
|
56
|
-
|
65
|
+
value_arr = []
|
66
|
+
value_fmt = String.new
|
67
|
+
value.each { |e| encode_field(e, value_arr, value_fmt) }
|
68
|
+
bytes = value_arr.pack(value_fmt)
|
69
|
+
arr.push("A", bytes.bytesize, bytes)
|
70
|
+
fmt << "aL>a*"
|
57
71
|
when Hash
|
58
72
|
bytes = Table.encode(value)
|
59
|
-
|
73
|
+
arr.push("F", bytes.bytesize, bytes)
|
74
|
+
fmt << "aL>a*"
|
60
75
|
when true
|
61
|
-
|
76
|
+
arr.push("t", 1)
|
77
|
+
fmt << "aC"
|
62
78
|
when false
|
63
|
-
|
79
|
+
arr.push("t", 0)
|
80
|
+
fmt << "aC"
|
64
81
|
when nil
|
65
|
-
|
82
|
+
arr << "V"
|
83
|
+
fmt << "a"
|
66
84
|
else raise ArgumentError, "unsupported table field type: #{value.class}"
|
67
85
|
end
|
86
|
+
nil
|
68
87
|
end
|
69
88
|
|
70
89
|
# Decodes a single value
|
71
|
-
# @return [Array<Integer, Object>] Bytes read and the parsed
|
90
|
+
# @return [Array<Integer, Object>] Bytes read and the parsed value
|
72
91
|
# @api private
|
73
|
-
def self.decode_field(bytes)
|
74
|
-
type = bytes[
|
75
|
-
pos
|
92
|
+
def self.decode_field(bytes, pos)
|
93
|
+
type = bytes[pos]
|
94
|
+
pos += 1
|
76
95
|
case type
|
77
96
|
when "S"
|
78
97
|
len = bytes.byteslice(pos, 4).unpack1("L>")
|
@@ -84,9 +103,11 @@ module AMQP
|
|
84
103
|
[4 + len, decode(bytes.byteslice(pos, len))]
|
85
104
|
when "A"
|
86
105
|
len = bytes.byteslice(pos, 4).unpack1("L>")
|
106
|
+
pos += 4
|
107
|
+
array_end = pos + len
|
87
108
|
a = []
|
88
|
-
while pos <
|
89
|
-
length, value = decode_field(bytes
|
109
|
+
while pos < array_end
|
110
|
+
length, value = decode_field(bytes, pos)
|
90
111
|
pos += length + 1
|
91
112
|
a << value
|
92
113
|
end
|
data/lib/amqp/client/version.rb
CHANGED
data/lib/amqp/client.rb
CHANGED
@@ -38,12 +38,18 @@ module AMQP
|
|
38
38
|
# Establishes and returns a new AMQP connection
|
39
39
|
# @see Connection#initialize
|
40
40
|
# @return [Connection]
|
41
|
+
# @example
|
42
|
+
# connection = AMQP::Client.new("amqps://server.rmq.cloudamqp.com", connection_name: "My connection").connect
|
41
43
|
def connect(read_loop_thread: true)
|
42
44
|
Connection.new(@uri, read_loop_thread: read_loop_thread, **@options)
|
43
45
|
end
|
44
46
|
|
45
47
|
# Opens an AMQP connection using the high level API, will try to reconnect if successfully connected at first
|
46
48
|
# @return [self]
|
49
|
+
# @example
|
50
|
+
# amqp = AMQP::Client.new("amqps://server.rmq.cloudamqp.com")
|
51
|
+
# amqp.start
|
52
|
+
# amqp.queue("foobar")
|
47
53
|
def start
|
48
54
|
@stopped = false
|
49
55
|
Thread.new(connect(read_loop_thread: false)) do |conn|
|
@@ -95,6 +101,10 @@ module AMQP
|
|
95
101
|
# (it won't be deleted until at least one consumer has consumed from it)
|
96
102
|
# @param arguments [Hash] Custom arguments, such as queue-ttl etc.
|
97
103
|
# @return [Queue]
|
104
|
+
# @example
|
105
|
+
# amqp = AMQP::Client.new.start
|
106
|
+
# q = amqp.queue("foobar")
|
107
|
+
# q.publish("body")
|
98
108
|
def queue(name, durable: true, auto_delete: false, arguments: {})
|
99
109
|
raise ArgumentError, "Currently only supports named, durable queues" if name.empty?
|
100
110
|
|
@@ -108,6 +118,10 @@ module AMQP
|
|
108
118
|
|
109
119
|
# Declare an exchange and return a high level Exchange object
|
110
120
|
# @return [Exchange]
|
121
|
+
# @example
|
122
|
+
# amqp = AMQP::Client.new.start
|
123
|
+
# x = amqp.exchange("my.hash.exchange", "x-consistent-hash")
|
124
|
+
# x.publish("body", "routing-key")
|
111
125
|
def exchange(name, type, durable: true, auto_delete: false, internal: false, arguments: {})
|
112
126
|
@exchanges.fetch(name) do
|
113
127
|
with_connection do |conn|
|
@@ -172,9 +186,7 @@ module AMQP
|
|
172
186
|
with_connection do |conn|
|
173
187
|
ch = conn.channel
|
174
188
|
ch.basic_qos(prefetch)
|
175
|
-
ch.basic_consume(queue, no_ack: no_ack, worker_threads: worker_threads, arguments: arguments)
|
176
|
-
blk.call(msg)
|
177
|
-
end
|
189
|
+
ch.basic_consume(queue, no_ack: no_ack, worker_threads: worker_threads, arguments: arguments, &blk)
|
178
190
|
end
|
179
191
|
end
|
180
192
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carl Hörberg
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Work in progress
|
14
14
|
email:
|
@@ -37,7 +37,7 @@ files:
|
|
37
37
|
- lib/amqp/client/connection.rb
|
38
38
|
- lib/amqp/client/errors.rb
|
39
39
|
- lib/amqp/client/exchange.rb
|
40
|
-
- lib/amqp/client/
|
40
|
+
- lib/amqp/client/frame_bytes.rb
|
41
41
|
- lib/amqp/client/message.rb
|
42
42
|
- lib/amqp/client/properties.rb
|
43
43
|
- lib/amqp/client/queue.rb
|