rabbitmq 0.2.3 → 0.2.4
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/README.md +3 -0
- data/ext/rabbitmq/Rakefile +14 -9
- data/lib/rabbitmq/connection/channel_manager.rb +61 -0
- data/lib/rabbitmq/connection/event_manager.rb +55 -0
- data/lib/rabbitmq/connection/transport.rb +157 -0
- data/lib/rabbitmq/ffi.rb +4 -356
- data/lib/rabbitmq/ffi/ext.rb +12 -299
- data/lib/rabbitmq/ffi/ext/basic_properties.rb +57 -0
- data/lib/rabbitmq/ffi/ext/bytes.rb +29 -0
- data/lib/rabbitmq/ffi/ext/connection_info.rb +12 -0
- data/lib/rabbitmq/ffi/ext/field_value.rb +49 -0
- data/lib/rabbitmq/ffi/ext/frame.rb +43 -0
- data/lib/rabbitmq/ffi/ext/frame_payload_properties.rb +12 -0
- data/lib/rabbitmq/ffi/ext/method.rb +49 -0
- data/lib/rabbitmq/ffi/ext/table.rb +51 -0
- data/lib/rabbitmq/ffi/ext/timeval.rb +18 -0
- data/lib/rabbitmq/ffi/gen.rb +65 -0
- data/lib/rabbitmq/ffi/gen/access_request.rb +49 -0
- data/lib/rabbitmq/ffi/gen/access_request_ok.rb +29 -0
- data/lib/rabbitmq/ffi/gen/basic_ack.rb +36 -0
- data/lib/rabbitmq/ffi/gen/basic_cancel.rb +37 -0
- data/lib/rabbitmq/ffi/gen/basic_cancel_ok.rb +30 -0
- data/lib/rabbitmq/ffi/gen/basic_consume.rb +57 -0
- data/lib/rabbitmq/ffi/gen/basic_consume_ok.rb +30 -0
- data/lib/rabbitmq/ffi/gen/basic_deliver.rb +48 -0
- data/lib/rabbitmq/ffi/gen/basic_get.rb +40 -0
- data/lib/rabbitmq/ffi/gen/basic_get_empty.rb +30 -0
- data/lib/rabbitmq/ffi/gen/basic_get_ok.rb +47 -0
- data/lib/rabbitmq/ffi/gen/basic_nack.rb +39 -0
- data/lib/rabbitmq/ffi/gen/basic_publish.rb +47 -0
- data/lib/rabbitmq/ffi/gen/basic_qos.rb +39 -0
- data/lib/rabbitmq/ffi/gen/basic_qos_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/basic_recover.rb +29 -0
- data/lib/rabbitmq/ffi/gen/basic_recover_async.rb +29 -0
- data/lib/rabbitmq/ffi/gen/basic_recover_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/basic_reject.rb +36 -0
- data/lib/rabbitmq/ffi/gen/basic_return.rb +45 -0
- data/lib/rabbitmq/ffi/gen/channel_close.rb +45 -0
- data/lib/rabbitmq/ffi/gen/channel_close_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/channel_flow.rb +29 -0
- data/lib/rabbitmq/ffi/gen/channel_flow_ok.rb +29 -0
- data/lib/rabbitmq/ffi/gen/channel_open.rb +30 -0
- data/lib/rabbitmq/ffi/gen/channel_open_ok.rb +30 -0
- data/lib/rabbitmq/ffi/gen/confirm_select.rb +29 -0
- data/lib/rabbitmq/ffi/gen/confirm_select_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/connection_blocked.rb +30 -0
- data/lib/rabbitmq/ffi/gen/connection_close.rb +45 -0
- data/lib/rabbitmq/ffi/gen/connection_close_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/connection_open.rb +41 -0
- data/lib/rabbitmq/ffi/gen/connection_open_ok.rb +30 -0
- data/lib/rabbitmq/ffi/gen/connection_secure.rb +30 -0
- data/lib/rabbitmq/ffi/gen/connection_secure_ok.rb +30 -0
- data/lib/rabbitmq/ffi/gen/connection_start.rb +48 -0
- data/lib/rabbitmq/ffi/gen/connection_start_ok.rb +46 -0
- data/lib/rabbitmq/ffi/gen/connection_tune.rb +39 -0
- data/lib/rabbitmq/ffi/gen/connection_tune_ok.rb +39 -0
- data/lib/rabbitmq/ffi/gen/connection_unblocked.rb +28 -0
- data/lib/rabbitmq/ffi/gen/exchange_bind.rb +52 -0
- data/lib/rabbitmq/ffi/gen/exchange_bind_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/exchange_declare.rb +60 -0
- data/lib/rabbitmq/ffi/gen/exchange_declare_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/exchange_delete.rb +43 -0
- data/lib/rabbitmq/ffi/gen/exchange_delete_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/exchange_unbind.rb +52 -0
- data/lib/rabbitmq/ffi/gen/exchange_unbind_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/queue_bind.rb +52 -0
- data/lib/rabbitmq/ffi/gen/queue_bind_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/queue_declare.rb +56 -0
- data/lib/rabbitmq/ffi/gen/queue_declare_ok.rb +40 -0
- data/lib/rabbitmq/ffi/gen/queue_delete.rb +46 -0
- data/lib/rabbitmq/ffi/gen/queue_delete_ok.rb +29 -0
- data/lib/rabbitmq/ffi/gen/queue_purge.rb +40 -0
- data/lib/rabbitmq/ffi/gen/queue_purge_ok.rb +29 -0
- data/lib/rabbitmq/ffi/gen/queue_unbind.rb +49 -0
- data/lib/rabbitmq/ffi/gen/queue_unbind_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/tx_commit.rb +28 -0
- data/lib/rabbitmq/ffi/gen/tx_commit_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/tx_rollback.rb +28 -0
- data/lib/rabbitmq/ffi/gen/tx_rollback_ok.rb +28 -0
- data/lib/rabbitmq/ffi/gen/tx_select.rb +28 -0
- data/lib/rabbitmq/ffi/gen/tx_select_ok.rb +28 -0
- metadata +79 -2
data/lib/rabbitmq/ffi/ext.rb
CHANGED
@@ -1,300 +1,13 @@
|
|
1
1
|
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
class << self; attr_reader :zero; end
|
15
|
-
end
|
16
|
-
|
17
|
-
class ConnectionInfo
|
18
|
-
def to_h
|
19
|
-
members.map { |k| [k, self[k]] }.to_h
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class Bytes
|
24
|
-
def to_s(free=false)
|
25
|
-
size = self[:len]
|
26
|
-
s = size == 0 ? "" : self[:bytes].read_bytes(size)
|
27
|
-
free! if free
|
28
|
-
s
|
29
|
-
end
|
30
|
-
|
31
|
-
def free!
|
32
|
-
FFI.free(self[:bytes])
|
33
|
-
clear
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.from_s(str)
|
37
|
-
size = str.bytesize
|
38
|
-
bytes = FFI.amqp_bytes_malloc(size)
|
39
|
-
|
40
|
-
bytes[:bytes].write_string(str)
|
41
|
-
bytes[:len] = size
|
42
|
-
bytes
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class FieldValue
|
47
|
-
private def value_member(kind)
|
48
|
-
case kind
|
49
|
-
when :utf8; :bytes
|
50
|
-
when :timestamp; :u64
|
51
|
-
else kind
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def to_value(free=false)
|
56
|
-
kind = self[:kind]
|
57
|
-
value = self[:value][value_member(kind)]
|
58
|
-
result = case kind
|
59
|
-
when :bytes; value.to_s(free)
|
60
|
-
when :utf8; value.to_s(free).force_encoding(Encoding::UTF_8)
|
61
|
-
when :timestamp; Time.at(value / 1000.0)
|
62
|
-
when :table; value.to_h(free)
|
63
|
-
when :array; value.to_array_not_yet_implemented!
|
64
|
-
when :decimal; value.to_value_not_yet_implemented!
|
65
|
-
else value
|
66
|
-
end
|
67
|
-
|
68
|
-
clear if free
|
69
|
-
result
|
70
|
-
end
|
71
|
-
|
72
|
-
def free!
|
73
|
-
kind = self[:kind]
|
74
|
-
value = self[:value][value_member(kind)]
|
75
|
-
value.free! if value.respond_to? :free!
|
76
|
-
clear
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.from(value)
|
80
|
-
obj = new
|
81
|
-
obj[:kind], obj[:value] = case value
|
82
|
-
when String; [:bytes, FieldValueValue.new(Bytes.from_s(value).pointer)]
|
83
|
-
else raise NotImplementedError
|
84
|
-
end
|
85
|
-
obj
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
class Table
|
90
|
-
include Enumerable
|
91
|
-
|
92
|
-
def each(*a, &b)
|
93
|
-
entry_ptr = self[:entries]
|
94
|
-
entries = self[:num_entries].times.map do |i|
|
95
|
-
FFI::TableEntry.new(entry_ptr + i * FFI::TableEntry.size)
|
96
|
-
end
|
97
|
-
entries.each(*a, &b)
|
98
|
-
end
|
99
|
-
|
100
|
-
def to_h(free=false)
|
101
|
-
result = self.map do |entry|
|
102
|
-
[entry[:key].to_s(free), entry[:value].to_value(free)]
|
103
|
-
end.to_h
|
104
|
-
|
105
|
-
clear if free
|
106
|
-
result
|
107
|
-
end
|
108
|
-
|
109
|
-
def free!
|
110
|
-
self.each do
|
111
|
-
entry[:key].free!
|
112
|
-
entry[:value].free!
|
113
|
-
end
|
114
|
-
FFI.free(self[:entries])
|
115
|
-
clear
|
116
|
-
end
|
117
|
-
|
118
|
-
def self.from(params)
|
119
|
-
size = params.size
|
120
|
-
entry_ptr = Util.mem_ptr(size * FFI::TableEntry.size, release: false)
|
121
|
-
params.each_with_index do |param, idx|
|
122
|
-
entry = FFI::TableEntry.new(entry_ptr + idx * FFI::TableEntry.size)
|
123
|
-
entry[:key] = FFI::Bytes.from_s(param.first.to_s)
|
124
|
-
entry[:value] = FFI::FieldValue.from(param.last)
|
125
|
-
end
|
126
|
-
|
127
|
-
obj = new
|
128
|
-
obj[:num_entries] = size
|
129
|
-
obj[:entries] = entry_ptr
|
130
|
-
obj
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
class Method
|
135
|
-
MethodClasses = FFI::MethodNumber.symbols.map do |name|
|
136
|
-
const_name = name.to_s.gsub(/((?:\A\w)|(?:_\w))/) { |x| x[-1].upcase }
|
137
|
-
[name, FFI.const_get(const_name)]
|
138
|
-
end.to_h.freeze
|
139
|
-
|
140
|
-
MethodNames = MethodClasses.to_a.map(&:reverse).to_h.freeze
|
141
|
-
|
142
|
-
def to_h(free=false)
|
143
|
-
{ method: self[:id],
|
144
|
-
properties: self.decoded.to_h(free) }
|
145
|
-
end
|
146
|
-
|
147
|
-
def decoded
|
148
|
-
MethodClasses.fetch(self[:id]).new(self[:decoded])
|
149
|
-
end
|
150
|
-
|
151
|
-
def self.lookup(kls)
|
152
|
-
MethodNames.fetch(kls)
|
153
|
-
end
|
154
|
-
|
155
|
-
def self.lookup_class(name)
|
156
|
-
MethodClasses.fetch(name)
|
157
|
-
end
|
158
|
-
|
159
|
-
def self.from(decoded)
|
160
|
-
obj = new
|
161
|
-
obj[:id] = lookup(decoded.class)
|
162
|
-
obj[:decoded] = decoded.pointer
|
163
|
-
obj
|
164
|
-
end
|
165
|
-
|
166
|
-
def self.has_content?(type)
|
167
|
-
case type
|
168
|
-
when :basic_publish; true
|
169
|
-
when :basic_return; true
|
170
|
-
when :basic_deliver; true
|
171
|
-
when :basic_get_ok; true
|
172
|
-
else false
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
module MethodClassMixin
|
178
|
-
def apply(**params)
|
179
|
-
params.each do |key, value|
|
180
|
-
next if value.nil? || !writable_key?(key)
|
181
|
-
case value
|
182
|
-
when String; value = FFI::Bytes.from_s(value)
|
183
|
-
when Hash; value = FFI::Table.from(value)
|
184
|
-
end
|
185
|
-
key_applied_hook(key)
|
186
|
-
self[key] = value
|
187
|
-
end
|
188
|
-
self
|
189
|
-
end
|
190
|
-
|
191
|
-
def to_h(free=false)
|
192
|
-
result = {}
|
193
|
-
self.members.each do |key| [key, self[key]]
|
194
|
-
next unless readable_key?(key)
|
195
|
-
value = self[key]
|
196
|
-
case value
|
197
|
-
when FFI::Bytes; value = value.to_s(free)
|
198
|
-
when FFI::Table; value = value.to_h(free)
|
199
|
-
end
|
200
|
-
result[key] = value
|
201
|
-
end
|
202
|
-
|
203
|
-
# TODO: handle the inverse case of this transformation in apply method
|
204
|
-
if (method_id = result.delete(:method_id))
|
205
|
-
method_num = (result.delete(:class_id) << 16) + method_id
|
206
|
-
result[:method] = FFI::MethodNumber[method_num]
|
207
|
-
end
|
208
|
-
|
209
|
-
clear if free
|
210
|
-
result
|
211
|
-
end
|
212
|
-
|
213
|
-
def free!
|
214
|
-
self.values.each do |item|
|
215
|
-
item.free! if item.respond_to? :free!
|
216
|
-
end
|
217
|
-
clear
|
218
|
-
end
|
219
|
-
|
220
|
-
def key_applied_hook(key)
|
221
|
-
# do nothing here
|
222
|
-
end
|
223
|
-
|
224
|
-
def readable_key?(key)
|
225
|
-
key != :dummy
|
226
|
-
end
|
227
|
-
|
228
|
-
def writable_key?(key)
|
229
|
-
key != :dummy
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
Method::MethodClasses.each { |_, kls| kls.send(:include, MethodClassMixin) }
|
234
|
-
|
235
|
-
BasicProperties.send(:include, MethodClassMixin)
|
236
|
-
|
237
|
-
class BasicProperties
|
238
|
-
def key_applied_hook(key)
|
239
|
-
flag_bit = FLAGS[key]
|
240
|
-
return unless flag_bit
|
241
|
-
self[:_flags] = (self[:_flags] | flag_bit)
|
242
|
-
end
|
243
|
-
|
244
|
-
def readable_key?(key)
|
245
|
-
return false if key == :_flags
|
246
|
-
flag_bit = FLAGS[key]
|
247
|
-
return true unless flag_bit
|
248
|
-
return (flag_bit & self[:_flags]) != 0
|
249
|
-
end
|
250
|
-
|
251
|
-
def writable_key?(key)
|
252
|
-
true
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
class FramePayloadProperties
|
257
|
-
def decoded
|
258
|
-
BasicProperties.new(self[:decoded])
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
class Frame
|
263
|
-
def payload
|
264
|
-
member = case self[:frame_type]
|
265
|
-
when :method; :method
|
266
|
-
when :header; :properties
|
267
|
-
when :body; :body_fragment
|
268
|
-
else; raise NotImplementedError, "frame type: #{self[:frame_type]}"
|
269
|
-
end
|
270
|
-
self[:payload][member]
|
271
|
-
end
|
272
|
-
|
273
|
-
def as_method_to_h(free=false)
|
274
|
-
# TODO: raise correct error class with enough info for appropriate action
|
275
|
-
raise "Wrong frame type for method frame of event: #{self[:frame_type]}" \
|
276
|
-
unless self[:frame_type] == :method
|
277
|
-
|
278
|
-
payload.to_h(free).merge(channel: self[:channel])
|
279
|
-
end
|
280
|
-
|
281
|
-
def as_header_to_h(free=false)
|
282
|
-
# TODO: raise correct error class with enough info for appropriate action
|
283
|
-
raise "Wrong frame type for header frame of multiframe event: #{self[:frame_type]}" \
|
284
|
-
unless self[:frame_type] == :header
|
285
|
-
|
286
|
-
properties = self[:payload][:properties]
|
287
|
-
{ header: properties.decoded.to_h(free), body_size: properties[:body_size] }
|
288
|
-
end
|
289
|
-
|
290
|
-
def as_body_to_s(free=false)
|
291
|
-
# TODO: raise correct error class with enough info for appropriate action
|
292
|
-
raise "Wrong frame type for body frame of multiframe event: #{self[:frame_type]}" \
|
293
|
-
unless self[:frame_type] == :body
|
294
|
-
|
295
|
-
self[:payload][:body_fragment].to_s(free)
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
end
|
300
|
-
end
|
2
|
+
require_relative 'ext/timeval'
|
3
|
+
require_relative 'ext/bytes'
|
4
|
+
|
5
|
+
require_relative 'ext/connection_info'
|
6
|
+
require_relative 'ext/field_value'
|
7
|
+
require_relative 'ext/table'
|
8
|
+
|
9
|
+
require_relative 'ext/method'
|
10
|
+
require_relative 'ext/basic_properties'
|
11
|
+
require_relative 'ext/frame_payload_properties'
|
12
|
+
|
13
|
+
require_relative 'ext/frame'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
module RabbitMQ
|
3
|
+
module FFI
|
4
|
+
|
5
|
+
class BasicProperties
|
6
|
+
def apply(**params)
|
7
|
+
params.each do |key, value|
|
8
|
+
next if value.nil?
|
9
|
+
case value
|
10
|
+
when String; value = FFI::Bytes.from_s(value)
|
11
|
+
when Hash; value = FFI::Table.from(value)
|
12
|
+
end
|
13
|
+
set_flag_for_key(key)
|
14
|
+
self[key] = value
|
15
|
+
end
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_h(free=false)
|
20
|
+
result = {}
|
21
|
+
self.members.each do |key| [key, self[key]]
|
22
|
+
next unless flag_for_key?(key)
|
23
|
+
value = self[key]
|
24
|
+
case value
|
25
|
+
when FFI::Bytes; value = value.to_s(free)
|
26
|
+
when FFI::Table; value = value.to_h(free)
|
27
|
+
end
|
28
|
+
result[key] = value
|
29
|
+
end
|
30
|
+
|
31
|
+
clear if free
|
32
|
+
result
|
33
|
+
end
|
34
|
+
|
35
|
+
def free!
|
36
|
+
self.values.each do |item|
|
37
|
+
item.free! if item.respond_to? :free!
|
38
|
+
end
|
39
|
+
clear
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_flag_for_key(key)
|
43
|
+
flag_bit = FLAGS[key]
|
44
|
+
return unless flag_bit
|
45
|
+
self[:_flags] = (self[:_flags] | flag_bit)
|
46
|
+
end
|
47
|
+
|
48
|
+
def flag_for_key?(key)
|
49
|
+
return false if key == :_flags
|
50
|
+
flag_bit = FLAGS[key]
|
51
|
+
return true unless flag_bit
|
52
|
+
return (flag_bit & self[:_flags]) != 0
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module RabbitMQ
|
3
|
+
module FFI
|
4
|
+
|
5
|
+
class Bytes
|
6
|
+
def to_s(free=false)
|
7
|
+
size = self[:len]
|
8
|
+
s = size == 0 ? "" : self[:bytes].read_bytes(size)
|
9
|
+
free! if free
|
10
|
+
s
|
11
|
+
end
|
12
|
+
|
13
|
+
def free!
|
14
|
+
FFI.free(self[:bytes])
|
15
|
+
clear
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.from_s(str)
|
19
|
+
size = str.bytesize
|
20
|
+
bytes = FFI.amqp_bytes_malloc(size)
|
21
|
+
|
22
|
+
bytes[:bytes].write_string(str)
|
23
|
+
bytes[:len] = size
|
24
|
+
bytes
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module RabbitMQ
|
3
|
+
module FFI
|
4
|
+
|
5
|
+
class FieldValue
|
6
|
+
private def value_member(kind)
|
7
|
+
case kind
|
8
|
+
when :utf8; :bytes
|
9
|
+
when :timestamp; :u64
|
10
|
+
else kind
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_value(free=false)
|
15
|
+
kind = self[:kind]
|
16
|
+
value = self[:value][value_member(kind)]
|
17
|
+
result = case kind
|
18
|
+
when :bytes; value.to_s(free)
|
19
|
+
when :utf8; value.to_s(free).force_encoding(Encoding::UTF_8)
|
20
|
+
when :timestamp; Time.at(value / 1000.0)
|
21
|
+
when :table; value.to_h(free)
|
22
|
+
when :array; value.to_array_not_yet_implemented!
|
23
|
+
when :decimal; value.to_value_not_yet_implemented!
|
24
|
+
else value
|
25
|
+
end
|
26
|
+
|
27
|
+
clear if free
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
def free!
|
32
|
+
kind = self[:kind]
|
33
|
+
value = self[:value][value_member(kind)]
|
34
|
+
value.free! if value.respond_to? :free!
|
35
|
+
clear
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.from(value)
|
39
|
+
obj = new
|
40
|
+
obj[:kind], obj[:value] = case value
|
41
|
+
when String; [:bytes, FieldValueValue.new(Bytes.from_s(value).pointer)]
|
42
|
+
else raise NotImplementedError
|
43
|
+
end
|
44
|
+
obj
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|