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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/ext/rabbitmq/Rakefile +14 -9
  4. data/lib/rabbitmq/connection/channel_manager.rb +61 -0
  5. data/lib/rabbitmq/connection/event_manager.rb +55 -0
  6. data/lib/rabbitmq/connection/transport.rb +157 -0
  7. data/lib/rabbitmq/ffi.rb +4 -356
  8. data/lib/rabbitmq/ffi/ext.rb +12 -299
  9. data/lib/rabbitmq/ffi/ext/basic_properties.rb +57 -0
  10. data/lib/rabbitmq/ffi/ext/bytes.rb +29 -0
  11. data/lib/rabbitmq/ffi/ext/connection_info.rb +12 -0
  12. data/lib/rabbitmq/ffi/ext/field_value.rb +49 -0
  13. data/lib/rabbitmq/ffi/ext/frame.rb +43 -0
  14. data/lib/rabbitmq/ffi/ext/frame_payload_properties.rb +12 -0
  15. data/lib/rabbitmq/ffi/ext/method.rb +49 -0
  16. data/lib/rabbitmq/ffi/ext/table.rb +51 -0
  17. data/lib/rabbitmq/ffi/ext/timeval.rb +18 -0
  18. data/lib/rabbitmq/ffi/gen.rb +65 -0
  19. data/lib/rabbitmq/ffi/gen/access_request.rb +49 -0
  20. data/lib/rabbitmq/ffi/gen/access_request_ok.rb +29 -0
  21. data/lib/rabbitmq/ffi/gen/basic_ack.rb +36 -0
  22. data/lib/rabbitmq/ffi/gen/basic_cancel.rb +37 -0
  23. data/lib/rabbitmq/ffi/gen/basic_cancel_ok.rb +30 -0
  24. data/lib/rabbitmq/ffi/gen/basic_consume.rb +57 -0
  25. data/lib/rabbitmq/ffi/gen/basic_consume_ok.rb +30 -0
  26. data/lib/rabbitmq/ffi/gen/basic_deliver.rb +48 -0
  27. data/lib/rabbitmq/ffi/gen/basic_get.rb +40 -0
  28. data/lib/rabbitmq/ffi/gen/basic_get_empty.rb +30 -0
  29. data/lib/rabbitmq/ffi/gen/basic_get_ok.rb +47 -0
  30. data/lib/rabbitmq/ffi/gen/basic_nack.rb +39 -0
  31. data/lib/rabbitmq/ffi/gen/basic_publish.rb +47 -0
  32. data/lib/rabbitmq/ffi/gen/basic_qos.rb +39 -0
  33. data/lib/rabbitmq/ffi/gen/basic_qos_ok.rb +28 -0
  34. data/lib/rabbitmq/ffi/gen/basic_recover.rb +29 -0
  35. data/lib/rabbitmq/ffi/gen/basic_recover_async.rb +29 -0
  36. data/lib/rabbitmq/ffi/gen/basic_recover_ok.rb +28 -0
  37. data/lib/rabbitmq/ffi/gen/basic_reject.rb +36 -0
  38. data/lib/rabbitmq/ffi/gen/basic_return.rb +45 -0
  39. data/lib/rabbitmq/ffi/gen/channel_close.rb +45 -0
  40. data/lib/rabbitmq/ffi/gen/channel_close_ok.rb +28 -0
  41. data/lib/rabbitmq/ffi/gen/channel_flow.rb +29 -0
  42. data/lib/rabbitmq/ffi/gen/channel_flow_ok.rb +29 -0
  43. data/lib/rabbitmq/ffi/gen/channel_open.rb +30 -0
  44. data/lib/rabbitmq/ffi/gen/channel_open_ok.rb +30 -0
  45. data/lib/rabbitmq/ffi/gen/confirm_select.rb +29 -0
  46. data/lib/rabbitmq/ffi/gen/confirm_select_ok.rb +28 -0
  47. data/lib/rabbitmq/ffi/gen/connection_blocked.rb +30 -0
  48. data/lib/rabbitmq/ffi/gen/connection_close.rb +45 -0
  49. data/lib/rabbitmq/ffi/gen/connection_close_ok.rb +28 -0
  50. data/lib/rabbitmq/ffi/gen/connection_open.rb +41 -0
  51. data/lib/rabbitmq/ffi/gen/connection_open_ok.rb +30 -0
  52. data/lib/rabbitmq/ffi/gen/connection_secure.rb +30 -0
  53. data/lib/rabbitmq/ffi/gen/connection_secure_ok.rb +30 -0
  54. data/lib/rabbitmq/ffi/gen/connection_start.rb +48 -0
  55. data/lib/rabbitmq/ffi/gen/connection_start_ok.rb +46 -0
  56. data/lib/rabbitmq/ffi/gen/connection_tune.rb +39 -0
  57. data/lib/rabbitmq/ffi/gen/connection_tune_ok.rb +39 -0
  58. data/lib/rabbitmq/ffi/gen/connection_unblocked.rb +28 -0
  59. data/lib/rabbitmq/ffi/gen/exchange_bind.rb +52 -0
  60. data/lib/rabbitmq/ffi/gen/exchange_bind_ok.rb +28 -0
  61. data/lib/rabbitmq/ffi/gen/exchange_declare.rb +60 -0
  62. data/lib/rabbitmq/ffi/gen/exchange_declare_ok.rb +28 -0
  63. data/lib/rabbitmq/ffi/gen/exchange_delete.rb +43 -0
  64. data/lib/rabbitmq/ffi/gen/exchange_delete_ok.rb +28 -0
  65. data/lib/rabbitmq/ffi/gen/exchange_unbind.rb +52 -0
  66. data/lib/rabbitmq/ffi/gen/exchange_unbind_ok.rb +28 -0
  67. data/lib/rabbitmq/ffi/gen/queue_bind.rb +52 -0
  68. data/lib/rabbitmq/ffi/gen/queue_bind_ok.rb +28 -0
  69. data/lib/rabbitmq/ffi/gen/queue_declare.rb +56 -0
  70. data/lib/rabbitmq/ffi/gen/queue_declare_ok.rb +40 -0
  71. data/lib/rabbitmq/ffi/gen/queue_delete.rb +46 -0
  72. data/lib/rabbitmq/ffi/gen/queue_delete_ok.rb +29 -0
  73. data/lib/rabbitmq/ffi/gen/queue_purge.rb +40 -0
  74. data/lib/rabbitmq/ffi/gen/queue_purge_ok.rb +29 -0
  75. data/lib/rabbitmq/ffi/gen/queue_unbind.rb +49 -0
  76. data/lib/rabbitmq/ffi/gen/queue_unbind_ok.rb +28 -0
  77. data/lib/rabbitmq/ffi/gen/tx_commit.rb +28 -0
  78. data/lib/rabbitmq/ffi/gen/tx_commit_ok.rb +28 -0
  79. data/lib/rabbitmq/ffi/gen/tx_rollback.rb +28 -0
  80. data/lib/rabbitmq/ffi/gen/tx_rollback_ok.rb +28 -0
  81. data/lib/rabbitmq/ffi/gen/tx_select.rb +28 -0
  82. data/lib/rabbitmq/ffi/gen/tx_select_ok.rb +28 -0
  83. metadata +79 -2
@@ -1,300 +1,13 @@
1
1
 
2
- module RabbitMQ
3
- module FFI
4
-
5
- class Timeval
6
- def self.from(seconds)
7
- obj = new
8
- obj[:tv_sec] = seconds.to_i
9
- obj[:tv_usec] = (seconds * 1_000_000).to_i
10
- obj
11
- end
12
-
13
- @zero = self.from(0)
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,12 @@
1
+
2
+ module RabbitMQ
3
+ module FFI
4
+
5
+ class ConnectionInfo
6
+ def to_h
7
+ members.zip(values).to_h
8
+ end
9
+ end
10
+
11
+ end
12
+ 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