rabbitmq 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/ext/rabbitmq/Rakefile +42 -0
- data/lib/rabbitmq.rb +6 -0
- data/lib/rabbitmq/connection.rb +112 -0
- data/lib/rabbitmq/ffi.rb +204 -125
- data/lib/rabbitmq/ffi/error.rb +42 -0
- data/lib/rabbitmq/ffi/ext.rb +63 -0
- data/lib/rabbitmq/util.rb +36 -0
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c1c764cdfb743927b47bbd5165898582458c656
|
4
|
+
data.tar.gz: dda4411b342ca6e609562976f6fc981d9eb67577
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d3cee85a69364b25a15087b264fb47c906bbd1dd94c76a9fb56ffb06171f093ef9ffa78363dabb0dca23c2def71bf2bbe45c2d4a9e0b029e92074beb6dd4c9e
|
7
|
+
data.tar.gz: 5d418e13636abdd2189c7b49072abdf2ca4a9ed053dc7711d2fc60d009067a8a3202ecb77548d3c77df671d84ce49c8d1991d8110e10352ad2813c5dd4b85da3
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Joe McIlvain
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
require 'rake/clean'
|
3
|
+
|
4
|
+
FILES = {}
|
5
|
+
|
6
|
+
task :default => :build
|
7
|
+
|
8
|
+
def self.file_task(filename, opts, &block)
|
9
|
+
name, dep = opts.is_a?(Hash) ? opts.to_a.first : [opts, nil]
|
10
|
+
|
11
|
+
FILES[name] = filename
|
12
|
+
CLEAN.include filename
|
13
|
+
task name => filename
|
14
|
+
|
15
|
+
if dep
|
16
|
+
file filename => FILES[dep], &block
|
17
|
+
else
|
18
|
+
file filename, &block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
file_task 'rabbitmq-c.tar.gz', :download_tarball do
|
23
|
+
version = "0.6.0"
|
24
|
+
release = "https://github.com/alanxz/rabbitmq-c/releases/download/v#{version}/rabbitmq-c-#{version}.tar.gz"
|
25
|
+
system "wget #{release}"
|
26
|
+
system "mv #{File.basename(release)} #{FILES[:download_tarball]}"
|
27
|
+
end
|
28
|
+
|
29
|
+
file_task 'rabbitmq-c', :download => :download_tarball do
|
30
|
+
system "tar -xf #{FILES[:download_tarball]}"
|
31
|
+
system "mv rabbitmq-c-* #{FILES[:download]}"
|
32
|
+
end
|
33
|
+
|
34
|
+
file_task 'config.status', :configure => :download do
|
35
|
+
system "bash -c 'cd #{FILES[:download]} && ./configure'"
|
36
|
+
system "cp #{FILES[:download]}/#{FILES[:configure]} ./"
|
37
|
+
end
|
38
|
+
|
39
|
+
file_task 'librabbitmq.so', :build => :configure do
|
40
|
+
system "bash -c 'cd #{FILES[:download]} && make'"
|
41
|
+
system "cp #{FILES[:download]}/librabbitmq/.libs/#{FILES[:build]} ."
|
42
|
+
end
|
data/lib/rabbitmq.rb
CHANGED
@@ -0,0 +1,112 @@
|
|
1
|
+
|
2
|
+
module RabbitMQ
|
3
|
+
class Connection
|
4
|
+
def initialize *args
|
5
|
+
@ptr = FFI.amqp_new_connection
|
6
|
+
parse_info(*args)
|
7
|
+
create_socket!
|
8
|
+
|
9
|
+
@finalizer = self.class.send :create_finalizer_for, @ptr
|
10
|
+
ObjectSpace.define_finalizer self, @finalizer
|
11
|
+
end
|
12
|
+
|
13
|
+
def destroy
|
14
|
+
if @finalizer
|
15
|
+
@finalizer.call
|
16
|
+
ObjectSpace.undefine_finalizer self
|
17
|
+
end
|
18
|
+
@ptr = @socket = @finalizer = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
class DestroyedError < RuntimeError; end
|
22
|
+
|
23
|
+
# @private
|
24
|
+
def self.create_finalizer_for(ptr)
|
25
|
+
Proc.new do
|
26
|
+
FFI.amqp_connection_close(ptr, 200)
|
27
|
+
FFI.amqp_destroy_connection(ptr)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def user; @info[:user]; end
|
32
|
+
def password; @info[:password]; end
|
33
|
+
def host; @info[:host]; end
|
34
|
+
def vhost; @info[:vhost]; end
|
35
|
+
def port; @info[:port]; end
|
36
|
+
def ssl?; @info[:ssl]; end
|
37
|
+
|
38
|
+
def max_channels; @max_channels ||= 0; end; attr_writer :max_channels
|
39
|
+
def max_frame_size; @max_frame_size ||= 131072; end; attr_writer :max_frame_size
|
40
|
+
def heartbeat_interval; 0; end # not fully implemented in librabbitmq
|
41
|
+
|
42
|
+
def start
|
43
|
+
close # Close if already open
|
44
|
+
connect_socket!
|
45
|
+
login!
|
46
|
+
open_channel!
|
47
|
+
end
|
48
|
+
|
49
|
+
def close
|
50
|
+
raise DestroyedError unless @ptr
|
51
|
+
FFI.amqp_connection_close(@ptr, 200)
|
52
|
+
end
|
53
|
+
|
54
|
+
private def parse_info url=nil
|
55
|
+
info = FFI::ConnectionInfo.new
|
56
|
+
|
57
|
+
if url
|
58
|
+
url_ptr = Util.strdup_ptr(url)
|
59
|
+
Util.error_check :"parsing connection URL",
|
60
|
+
FFI.amqp_parse_url(url_ptr, info)
|
61
|
+
|
62
|
+
# We must copy ConnectionInfo before the url_ptr is freed.
|
63
|
+
@info = info.to_h
|
64
|
+
url_ptr.free
|
65
|
+
else
|
66
|
+
FFI.amqp_default_connection_info(info)
|
67
|
+
@info = info.to_h
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private def create_socket!
|
72
|
+
raise DestroyedError unless @ptr
|
73
|
+
|
74
|
+
@socket = FFI.amqp_tcp_socket_new(@ptr)
|
75
|
+
Util.null_check :"creating a socket", @socket
|
76
|
+
end
|
77
|
+
|
78
|
+
private def connect_socket!
|
79
|
+
raise DestroyedError unless @ptr
|
80
|
+
raise NotImplementedError if ssl?
|
81
|
+
|
82
|
+
create_socket!
|
83
|
+
Util.error_check :"opening a socket",
|
84
|
+
FFI.amqp_socket_open(@socket, host, port)
|
85
|
+
end
|
86
|
+
|
87
|
+
private def login!
|
88
|
+
raise DestroyedError unless @ptr
|
89
|
+
|
90
|
+
rpc_check :"logging in",
|
91
|
+
FFI.amqp_login(@ptr, vhost, max_channels, max_frame_size,
|
92
|
+
heartbeat_interval, :plain, :string, user, :string, password)
|
93
|
+
|
94
|
+
@server_properties = FFI::Table.new(FFI.amqp_get_server_properties(@ptr)).to_h
|
95
|
+
end
|
96
|
+
|
97
|
+
private def open_channel!(number=1)
|
98
|
+
raise DestroyedError unless @ptr
|
99
|
+
|
100
|
+
FFI.amqp_channel_open(@ptr, number)
|
101
|
+
rpc_check :"opening channel", FFI.amqp_get_rpc_reply(@ptr)
|
102
|
+
end
|
103
|
+
|
104
|
+
private def rpc_check action, res
|
105
|
+
case res[:reply_type]
|
106
|
+
when :library_exception; Util.error_check action, res[:library_error]
|
107
|
+
when :server_exception; raise NotImplementedError
|
108
|
+
else res
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/lib/rabbitmq/ffi.rb
CHANGED
@@ -6,24 +6,10 @@ module RabbitMQ
|
|
6
6
|
module FFI
|
7
7
|
extend ::FFI::Library
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
begin
|
14
|
-
lib_name = 'librabbitmq'
|
15
|
-
lib_paths = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
|
16
|
-
.map { |path| "#{path}/#{lib_name}.#{::FFI::Platform::LIBSUFFIX}" }
|
17
|
-
ffi_lib lib_paths + [lib_name]
|
18
|
-
@available = true
|
19
|
-
rescue LoadError
|
20
|
-
warn ""
|
21
|
-
warn "WARNING: #{self} is not available without librabbitmq."
|
22
|
-
warn ""
|
23
|
-
@available = false
|
24
|
-
end
|
9
|
+
ffi_lib \
|
10
|
+
File.expand_path("../../ext/rabbitmq/librabbitmq.so", File.dirname(__FILE__))
|
25
11
|
|
26
|
-
|
12
|
+
begin # TODO: remove begin/end block
|
27
13
|
opts = {
|
28
14
|
blocking: true # only necessary on MRI to deal with the GIL.
|
29
15
|
}
|
@@ -33,10 +19,87 @@ module RabbitMQ
|
|
33
19
|
attach_function :amqp_version_number, [], :uint32, **opts
|
34
20
|
attach_function :amqp_version, [], :string, **opts
|
35
21
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
22
|
+
class Timeval < ::FFI::Struct
|
23
|
+
layout :tv_sec, :time_t,
|
24
|
+
:tv_usec, :suseconds_t
|
25
|
+
end
|
26
|
+
|
27
|
+
class Boolean
|
28
|
+
extend ::FFI::DataConverter
|
29
|
+
native_type ::FFI::TypeDefs[:int]
|
30
|
+
def self.to_native val, ctx; val ? 1 : 0; end
|
31
|
+
def self.from_native val, ctx; val != 0; end
|
32
|
+
end
|
33
|
+
|
34
|
+
MethodNumber = enum ::FFI::TypeDefs[:uint32], [
|
35
|
+
:connection_start, 0x000A000A, # 10, 10; 655370
|
36
|
+
:connection_start_ok, 0x000A000B, # 10, 11; 655371
|
37
|
+
:connection_secure, 0x000A0014, # 10, 20; 655380
|
38
|
+
:connection_secure_ok, 0x000A0015, # 10, 21; 655381
|
39
|
+
:connection_tune, 0x000A001E, # 10, 30; 655390
|
40
|
+
:connection_tune_ok, 0x000A001F, # 10, 31; 655391
|
41
|
+
:connection_open, 0x000A0028, # 10, 40; 655400
|
42
|
+
:connection_open_ok, 0x000A0029, # 10, 41; 655401
|
43
|
+
:connection_close, 0x000A0032, # 10, 50; 655410
|
44
|
+
:connection_close_ok, 0x000A0033, # 10, 51; 655411
|
45
|
+
:connection_blocked, 0x000A003C, # 10, 60; 655420
|
46
|
+
:connection_unblocked, 0x000A003D, # 10, 61; 655421
|
47
|
+
:channel_open, 0x0014000A, # 20, 10; 1310730
|
48
|
+
:channel_open_ok, 0x0014000B, # 20, 11; 1310731
|
49
|
+
:channel_flow, 0x00140014, # 20, 20; 1310740
|
50
|
+
:channel_flow_ok, 0x00140015, # 20, 21; 1310741
|
51
|
+
:channel_close, 0x00140028, # 20, 40; 1310760
|
52
|
+
:channel_close_ok, 0x00140029, # 20, 41; 1310761
|
53
|
+
:access_request, 0x001E000A, # 30, 10; 1966090
|
54
|
+
:access_request_ok, 0x001E000B, # 30, 11; 1966091
|
55
|
+
:exchange_declare, 0x0028000A, # 40, 10; 2621450
|
56
|
+
:exchange_declare_ok, 0x0028000B, # 40, 11; 2621451
|
57
|
+
:exchange_delete, 0x00280014, # 40, 20; 2621460
|
58
|
+
:exchange_delete_ok, 0x00280015, # 40, 21; 2621461
|
59
|
+
:exchange_bind, 0x0028001E, # 40, 30; 2621470
|
60
|
+
:exchange_bind_ok, 0x0028001F, # 40, 31; 2621471
|
61
|
+
:exchange_unbind, 0x00280028, # 40, 40; 2621480
|
62
|
+
:exchange_unbind_ok, 0x00280033, # 40, 51; 2621491
|
63
|
+
:queue_declare, 0x0032000A, # 50, 10; 3276810
|
64
|
+
:queue_declare_ok, 0x0032000B, # 50, 11; 3276811
|
65
|
+
:queue_bind, 0x00320014, # 50, 20; 3276820
|
66
|
+
:queue_bind_ok, 0x00320015, # 50, 21; 3276821
|
67
|
+
:queue_purge, 0x0032001E, # 50, 30; 3276830
|
68
|
+
:queue_purge_ok, 0x0032001F, # 50, 31; 3276831
|
69
|
+
:queue_delete, 0x00320028, # 50, 40; 3276840
|
70
|
+
:queue_delete_ok, 0x00320029, # 50, 41; 3276841
|
71
|
+
:queue_unbind, 0x00320032, # 50, 50; 3276850
|
72
|
+
:queue_unbind_ok, 0x00320033, # 50, 51; 3276851
|
73
|
+
:basic_qos, 0x003C000A, # 60, 10; 3932170
|
74
|
+
:basic_qos_ok, 0x003C000B, # 60, 11; 3932171
|
75
|
+
:basic_consume, 0x003C0014, # 60, 20; 3932180
|
76
|
+
:basic_consume_ok, 0x003C0015, # 60, 21; 3932181
|
77
|
+
:basic_cancel, 0x003C001E, # 60, 30; 3932190
|
78
|
+
:basic_cancel_ok, 0x003C001F, # 60, 31; 3932191
|
79
|
+
:basic_publish, 0x003C0028, # 60, 40; 3932200
|
80
|
+
:basic_return, 0x003C0032, # 60, 50; 3932210
|
81
|
+
:basic_deliver, 0x003C003C, # 60, 60; 3932220
|
82
|
+
:basic_get, 0x003C0046, # 60, 70; 3932230
|
83
|
+
:basic_get_ok, 0x003C0047, # 60, 71; 3932231
|
84
|
+
:basic_get_empty, 0x003C0048, # 60, 72; 3932232
|
85
|
+
:basic_ack, 0x003C0050, # 60, 80; 3932240
|
86
|
+
:basic_reject, 0x003C005A, # 60, 90; 3932250
|
87
|
+
:basic_recover_async, 0x003C0064, # 60, 100; 3932260
|
88
|
+
:basic_recover, 0x003C006E, # 60, 110; 3932270
|
89
|
+
:basic_recover_ok, 0x003C006F, # 60, 111; 3932271
|
90
|
+
:basic_nack, 0x003C0078, # 60, 120; 3932280
|
91
|
+
:tx_select, 0x005A000A, # 90, 10; 5898250
|
92
|
+
:tx_select_ok, 0x005A000B, # 90, 11; 5898251
|
93
|
+
:tx_commit, 0x005A0014, # 90, 20; 5898260
|
94
|
+
:tx_commit_ok, 0x005A0015, # 90, 21; 5898261
|
95
|
+
:tx_rollback, 0x005A001E, # 90, 30; 5898270
|
96
|
+
:tx_rollback_ok, 0x005A001F, # 90, 31; 5898271
|
97
|
+
:confirm_select, 0x0055000A, # 85, 10; 5570570
|
98
|
+
:confirm_select_ok, 0x0055000B, # 85, 11; 5570571
|
99
|
+
]
|
100
|
+
|
101
|
+
Flags = :uint32
|
102
|
+
Channel = :uint16
|
40
103
|
|
41
104
|
class Bytes < ::FFI::Struct
|
42
105
|
layout :len, :size_t,
|
@@ -58,6 +121,27 @@ module RabbitMQ
|
|
58
121
|
:entries, :pointer
|
59
122
|
end
|
60
123
|
|
124
|
+
FieldValueKind = enum ::FFI::TypeDefs[:uint8], [
|
125
|
+
:boolean, 't'.ord,
|
126
|
+
:i8, 'b'.ord,
|
127
|
+
:u8, 'B'.ord,
|
128
|
+
:i16, 's'.ord,
|
129
|
+
:u16, 'u'.ord,
|
130
|
+
:i32, 'I'.ord,
|
131
|
+
:u32, 'i'.ord,
|
132
|
+
:i64, 'l'.ord,
|
133
|
+
:u64, 'L'.ord,
|
134
|
+
:f32, 'f'.ord,
|
135
|
+
:f64, 'd'.ord,
|
136
|
+
:decimal, 'D'.ord,
|
137
|
+
:utf8, 'S'.ord,
|
138
|
+
:array, 'A'.ord,
|
139
|
+
:timestamp, 'T'.ord,
|
140
|
+
:table, 'F'.ord,
|
141
|
+
:void, 'V'.ord,
|
142
|
+
:bytes, 'x'.ord,
|
143
|
+
]
|
144
|
+
|
61
145
|
class FieldValueValue < ::FFI::Union
|
62
146
|
layout :boolean, Boolean,
|
63
147
|
:i8, :int8,
|
@@ -77,7 +161,7 @@ module RabbitMQ
|
|
77
161
|
end
|
78
162
|
|
79
163
|
class FieldValue < ::FFI::Struct
|
80
|
-
layout :kind,
|
164
|
+
layout :kind, FieldValueKind,
|
81
165
|
:value, FieldValueValue
|
82
166
|
end
|
83
167
|
|
@@ -86,27 +170,6 @@ module RabbitMQ
|
|
86
170
|
:value, FieldValue
|
87
171
|
end
|
88
172
|
|
89
|
-
FieldValueKindEnum = enum [
|
90
|
-
:boolean, 't'.ord,
|
91
|
-
:i8, 'b'.ord,
|
92
|
-
:u8, 'B'.ord,
|
93
|
-
:i16, 's'.ord,
|
94
|
-
:u16, 'u'.ord,
|
95
|
-
:i32, 'I'.ord,
|
96
|
-
:u32, 'i'.ord,
|
97
|
-
:i64, 'l'.ord,
|
98
|
-
:u64, 'L'.ord,
|
99
|
-
:f32, 'f'.ord,
|
100
|
-
:f64, 'd'.ord,
|
101
|
-
:decimal, 'D'.ord,
|
102
|
-
:utf8, 'S'.ord,
|
103
|
-
:array, 'A'.ord,
|
104
|
-
:timestamp, 'T'.ord,
|
105
|
-
:table, 'F'.ord,
|
106
|
-
:void, 'V'.ord,
|
107
|
-
:bytes, 'x'.ord,
|
108
|
-
]
|
109
|
-
|
110
173
|
class PoolBlocklist < ::FFI::Struct
|
111
174
|
layout :num_blocks, :int,
|
112
175
|
:blocklist, :pointer
|
@@ -153,7 +216,7 @@ module RabbitMQ
|
|
153
216
|
:payload, FramePayload
|
154
217
|
end
|
155
218
|
|
156
|
-
|
219
|
+
ResponseType = enum [
|
157
220
|
:none, 0,
|
158
221
|
:normal,
|
159
222
|
:library_exception,
|
@@ -161,18 +224,18 @@ module RabbitMQ
|
|
161
224
|
]
|
162
225
|
|
163
226
|
class RpcReply < ::FFI::Struct
|
164
|
-
layout :reply_type,
|
227
|
+
layout :reply_type, ResponseType,
|
165
228
|
:reply, Method,
|
166
229
|
:library_error, :int
|
167
230
|
end
|
168
231
|
|
169
|
-
|
232
|
+
SaslMethod = enum [
|
170
233
|
:plain, 0,
|
171
234
|
]
|
172
235
|
|
173
236
|
ConnectionState = :pointer
|
174
237
|
|
175
|
-
|
238
|
+
Status = enum [
|
176
239
|
:ok, 0x0,
|
177
240
|
:no_memory, -0x0001,
|
178
241
|
:bad_amqp_data, -0x0002,
|
@@ -190,6 +253,8 @@ module RabbitMQ
|
|
190
253
|
:timer_failure, -0x000E,
|
191
254
|
:heartbeat_timeout, -0x000F,
|
192
255
|
:unexpected_state, -0x0010,
|
256
|
+
:unexpected_socket_closed, -0x0011,
|
257
|
+
:unexpected_socket_inuse, -0x0012,
|
193
258
|
:tcp_error, -0x0100,
|
194
259
|
:tcp_socketlib_init_error, -0x0101,
|
195
260
|
:ssl_error, -0x0200,
|
@@ -198,7 +263,7 @@ module RabbitMQ
|
|
198
263
|
:ssl_connection_failed, -0x0203,
|
199
264
|
]
|
200
265
|
|
201
|
-
|
266
|
+
DeliveryMode = enum [
|
202
267
|
:nonpersistent, 1,
|
203
268
|
:persistent, 2,
|
204
269
|
]
|
@@ -208,10 +273,10 @@ module RabbitMQ
|
|
208
273
|
|
209
274
|
attach_function :amqp_method_name, [MethodNumber], :string, **opts
|
210
275
|
attach_function :amqp_method_has_content, [MethodNumber], Boolean, **opts
|
211
|
-
attach_function :amqp_decode_method, [MethodNumber,
|
212
|
-
attach_function :amqp_decode_properties, [:uint16,
|
213
|
-
attach_function :amqp_encode_method, [MethodNumber, :pointer, Bytes],
|
214
|
-
attach_function :amqp_encode_properties, [:uint16, :pointer, Bytes],
|
276
|
+
attach_function :amqp_decode_method, [MethodNumber, Pool.ptr, Bytes, :pointer], Status, **opts
|
277
|
+
attach_function :amqp_decode_properties, [:uint16, Pool.ptr, Bytes, :pointer], Status, **opts
|
278
|
+
attach_function :amqp_encode_method, [MethodNumber, :pointer, Bytes], Status, **opts
|
279
|
+
attach_function :amqp_encode_properties, [:uint16, :pointer, Bytes], Status, **opts
|
215
280
|
|
216
281
|
class ConnectionStart < ::FFI::Struct
|
217
282
|
layout :version_major, :uint8,
|
@@ -622,31 +687,31 @@ module RabbitMQ
|
|
622
687
|
:cluster_id, Bytes
|
623
688
|
end
|
624
689
|
|
625
|
-
attach_function :amqp_channel_open, [ConnectionState, Channel],
|
626
|
-
attach_function :amqp_channel_flow, [ConnectionState, Channel, Boolean],
|
627
|
-
attach_function :amqp_exchange_declare, [ConnectionState, Channel, Bytes, Bytes, Boolean, Boolean, Table],
|
628
|
-
attach_function :amqp_exchange_delete, [ConnectionState, Channel, Bytes, Boolean],
|
629
|
-
attach_function :amqp_exchange_bind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table],
|
630
|
-
attach_function :amqp_exchange_unbind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table],
|
631
|
-
attach_function :amqp_queue_declare, [ConnectionState, Channel, Bytes, Boolean, Boolean, Boolean, Boolean, Table],
|
632
|
-
attach_function :amqp_queue_bind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table],
|
633
|
-
attach_function :amqp_queue_purge, [ConnectionState, Channel, Bytes],
|
634
|
-
attach_function :amqp_queue_delete, [ConnectionState, Channel, Bytes, Boolean, Boolean],
|
635
|
-
attach_function :amqp_queue_unbind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table],
|
636
|
-
attach_function :amqp_basic_qos, [ConnectionState, Channel, :uint32, :uint16, Boolean],
|
637
|
-
attach_function :amqp_basic_consume, [ConnectionState, Channel, Bytes, Bytes, Boolean, Boolean, Boolean, Table],
|
638
|
-
attach_function :amqp_basic_cancel, [ConnectionState, Channel, Bytes],
|
639
|
-
attach_function :amqp_basic_recover, [ConnectionState, Channel, Boolean],
|
640
|
-
attach_function :amqp_tx_select, [ConnectionState, Channel],
|
641
|
-
attach_function :amqp_tx_commit, [ConnectionState, Channel],
|
642
|
-
attach_function :amqp_tx_rollback, [ConnectionState, Channel],
|
643
|
-
attach_function :amqp_confirm_select, [ConnectionState, Channel],
|
644
|
-
|
645
|
-
attach_function :init_amqp_pool, [
|
646
|
-
attach_function :recycle_amqp_pool, [
|
647
|
-
attach_function :empty_amqp_pool, [
|
648
|
-
attach_function :amqp_pool_alloc, [
|
649
|
-
attach_function :amqp_pool_alloc_bytes, [
|
690
|
+
attach_function :amqp_channel_open, [ConnectionState, Channel], ChannelOpenOk.ptr, **opts
|
691
|
+
attach_function :amqp_channel_flow, [ConnectionState, Channel, Boolean], ChannelFlowOk.ptr, **opts
|
692
|
+
attach_function :amqp_exchange_declare, [ConnectionState, Channel, Bytes, Bytes, Boolean, Boolean, Table], ExchangeDeclareOk.ptr, **opts
|
693
|
+
attach_function :amqp_exchange_delete, [ConnectionState, Channel, Bytes, Boolean], ExchangeDeleteOk.ptr, **opts
|
694
|
+
attach_function :amqp_exchange_bind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table], ExchangeBindOk.ptr, **opts
|
695
|
+
attach_function :amqp_exchange_unbind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table], ExchangeUnbindOk.ptr, **opts
|
696
|
+
attach_function :amqp_queue_declare, [ConnectionState, Channel, Bytes, Boolean, Boolean, Boolean, Boolean, Table], QueueDeclareOk.ptr, **opts
|
697
|
+
attach_function :amqp_queue_bind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table], QueueBindOk.ptr, **opts
|
698
|
+
attach_function :amqp_queue_purge, [ConnectionState, Channel, Bytes], QueuePurgeOk.ptr, **opts
|
699
|
+
attach_function :amqp_queue_delete, [ConnectionState, Channel, Bytes, Boolean, Boolean], QueueDeleteOk.ptr, **opts
|
700
|
+
attach_function :amqp_queue_unbind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table], QueueUnbindOk.ptr, **opts
|
701
|
+
attach_function :amqp_basic_qos, [ConnectionState, Channel, :uint32, :uint16, Boolean], BasicQosOk.ptr, **opts
|
702
|
+
attach_function :amqp_basic_consume, [ConnectionState, Channel, Bytes, Bytes, Boolean, Boolean, Boolean, Table], BasicConsumeOk.ptr, **opts
|
703
|
+
attach_function :amqp_basic_cancel, [ConnectionState, Channel, Bytes], BasicCancelOk.ptr, **opts
|
704
|
+
attach_function :amqp_basic_recover, [ConnectionState, Channel, Boolean], BasicRecoverOk.ptr, **opts
|
705
|
+
attach_function :amqp_tx_select, [ConnectionState, Channel], TxSelect.ptr, **opts
|
706
|
+
attach_function :amqp_tx_commit, [ConnectionState, Channel], TxCommit.ptr, **opts
|
707
|
+
attach_function :amqp_tx_rollback, [ConnectionState, Channel], TxRollback.ptr, **opts
|
708
|
+
attach_function :amqp_confirm_select, [ConnectionState, Channel], ConfirmSelect.ptr, **opts
|
709
|
+
|
710
|
+
attach_function :init_amqp_pool, [Pool.ptr, :size_t], :void, **opts
|
711
|
+
attach_function :recycle_amqp_pool, [Pool.ptr], :void, **opts
|
712
|
+
attach_function :empty_amqp_pool, [Pool.ptr], :void, **opts
|
713
|
+
attach_function :amqp_pool_alloc, [Pool.ptr, :size_t], :pointer, **opts
|
714
|
+
attach_function :amqp_pool_alloc_bytes, [Pool.ptr, :size_t, Bytes.ptr], :void, **opts
|
650
715
|
|
651
716
|
attach_function :amqp_cstring_bytes, [:string], Bytes, **opts
|
652
717
|
attach_function :amqp_bytes_malloc_dup, [Bytes], Bytes, **opts
|
@@ -654,51 +719,55 @@ module RabbitMQ
|
|
654
719
|
attach_function :amqp_bytes_free, [Bytes], :void, **opts
|
655
720
|
|
656
721
|
attach_function :amqp_new_connection, [], ConnectionState, **opts
|
657
|
-
attach_function :amqp_get_sockfd, [ConnectionState], :int,
|
658
|
-
attach_function :amqp_set_sockfd, [ConnectionState, :int], :void,
|
659
|
-
attach_function :amqp_tune_connection, [ConnectionState, :int, :int, :int],
|
660
|
-
attach_function :amqp_get_channel_max, [ConnectionState], :int,
|
661
|
-
attach_function :
|
662
|
-
|
663
|
-
attach_function :
|
664
|
-
|
665
|
-
attach_function :
|
666
|
-
attach_function :
|
667
|
-
attach_function :
|
668
|
-
attach_function :
|
722
|
+
attach_function :amqp_get_sockfd, [ConnectionState], :int, **opts
|
723
|
+
attach_function :amqp_set_sockfd, [ConnectionState, :int], :void, **opts
|
724
|
+
attach_function :amqp_tune_connection, [ConnectionState, :int, :int, :int], Status, **opts
|
725
|
+
attach_function :amqp_get_channel_max, [ConnectionState], :int, **opts
|
726
|
+
attach_function :amqp_get_frame_max, [ConnectionState], :int, **opts
|
727
|
+
attach_function :amqp_get_heartbeat, [ConnectionState], :int, **opts
|
728
|
+
attach_function :amqp_destroy_connection, [ConnectionState], Status, **opts
|
729
|
+
|
730
|
+
attach_function :amqp_handle_input, [ConnectionState, Bytes, Frame.ptr], Status, **opts
|
731
|
+
attach_function :amqp_release_buffers_ok, [ConnectionState], Boolean, **opts
|
732
|
+
attach_function :amqp_release_buffers, [ConnectionState], :void, **opts
|
733
|
+
attach_function :amqp_maybe_release_buffers, [ConnectionState], :void, **opts
|
734
|
+
attach_function :amqp_maybe_release_buffers_on_channel, [ConnectionState, Channel], :void, **opts
|
735
|
+
attach_function :amqp_send_frame, [ConnectionState, Frame.ptr], Status, **opts
|
669
736
|
|
670
737
|
attach_function :amqp_table_entry_cmp, [:pointer, :pointer], :int, **opts
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
attach_function :
|
675
|
-
attach_function :
|
676
|
-
attach_function :
|
677
|
-
attach_function :
|
678
|
-
attach_function :
|
679
|
-
|
680
|
-
|
681
|
-
attach_function :
|
682
|
-
attach_function :
|
683
|
-
attach_function :
|
684
|
-
attach_function :
|
685
|
-
attach_function :
|
686
|
-
attach_function :
|
687
|
-
|
688
|
-
|
689
|
-
attach_function :
|
690
|
-
|
691
|
-
attach_function :
|
692
|
-
attach_function :
|
738
|
+
|
739
|
+
attach_function :amqp_open_socket, [:string, :int], Status, **opts
|
740
|
+
|
741
|
+
attach_function :amqp_send_header, [ConnectionState], Status, **opts
|
742
|
+
attach_function :amqp_frames_enqueued, [ConnectionState], Boolean, **opts
|
743
|
+
attach_function :amqp_simple_wait_frame, [ConnectionState, Frame.ptr], Status, **opts
|
744
|
+
attach_function :amqp_simple_wait_frame_noblock, [ConnectionState, Frame.ptr, Timeval.ptr], Status, **opts
|
745
|
+
attach_function :amqp_simple_wait_method, [ConnectionState, Channel, MethodNumber, Method.ptr], Status, **opts
|
746
|
+
attach_function :amqp_send_method, [ConnectionState, Channel, MethodNumber, Method.ptr], Status, **opts
|
747
|
+
|
748
|
+
attach_function :amqp_simple_rpc, [ConnectionState, Channel, MethodNumber, :pointer, :pointer], RpcReply.by_value, **opts
|
749
|
+
attach_function :amqp_simple_rpc_decoded, [ConnectionState, Channel, MethodNumber, MethodNumber, :pointer], :pointer, **opts
|
750
|
+
attach_function :amqp_get_rpc_reply, [ConnectionState], RpcReply.by_value, **opts
|
751
|
+
attach_function :amqp_login, [ConnectionState, :string, :int, :int, :int, SaslMethod, :varargs], RpcReply.by_value, **opts
|
752
|
+
attach_function :amqp_login_with_properties, [ConnectionState, :string, :int, :int, :int, Table.ptr, SaslMethod, :varargs], RpcReply.by_value, **opts
|
753
|
+
attach_function :amqp_channel_close, [ConnectionState, Channel, :int], RpcReply.by_value, **opts
|
754
|
+
attach_function :amqp_connection_close, [ConnectionState, :int], RpcReply.by_value, **opts
|
755
|
+
|
756
|
+
attach_function :amqp_basic_publish, [ConnectionState, Channel, Bytes, Bytes, Boolean, Boolean, BasicProperties.ptr, Bytes], RpcReply.by_value, **opts
|
757
|
+
|
758
|
+
attach_function :amqp_basic_get, [ConnectionState, Channel, Bytes, Boolean], Status, **opts
|
759
|
+
attach_function :amqp_basic_ack, [ConnectionState, Channel, :uint64, Boolean], Status, **opts
|
760
|
+
attach_function :amqp_basic_reject, [ConnectionState, Channel, :uint64, Boolean], Status, **opts
|
761
|
+
attach_function :amqp_basic_nack, [ConnectionState, Channel, :uint64, Boolean, Boolean], Status, **opts
|
693
762
|
|
694
763
|
attach_function :amqp_data_in_buffer, [ConnectionState], Boolean, **opts
|
695
764
|
|
696
765
|
attach_function :amqp_error_string, [:int], :string, **opts
|
697
766
|
attach_function :amqp_error_string2, [:int], :string, **opts
|
698
767
|
|
699
|
-
attach_function :amqp_decode_table, [Bytes,
|
700
|
-
attach_function :amqp_encode_table, [Bytes,
|
701
|
-
attach_function :amqp_table_clone, [
|
768
|
+
attach_function :amqp_decode_table, [Bytes, Pool.ptr, Table.ptr, :pointer], Status, **opts
|
769
|
+
attach_function :amqp_encode_table, [Bytes, Table.ptr, :pointer], Status, **opts
|
770
|
+
attach_function :amqp_table_clone, [Table.ptr, Table.ptr, Pool.ptr], Status, **opts
|
702
771
|
|
703
772
|
class Message < ::FFI::Struct
|
704
773
|
layout :properties, BasicProperties,
|
@@ -706,8 +775,8 @@ module RabbitMQ
|
|
706
775
|
:pool, Pool
|
707
776
|
end
|
708
777
|
|
709
|
-
attach_function :amqp_read_message, [ConnectionState, Channel,
|
710
|
-
attach_function :amqp_destroy_message, [
|
778
|
+
attach_function :amqp_read_message, [ConnectionState, Channel, Message.ptr, :int], RpcReply.by_value, **opts
|
779
|
+
attach_function :amqp_destroy_message, [Message.ptr], :void, **opts
|
711
780
|
|
712
781
|
class Envelope < ::FFI::Struct
|
713
782
|
layout :channel, Channel,
|
@@ -719,8 +788,8 @@ module RabbitMQ
|
|
719
788
|
:message, Message
|
720
789
|
end
|
721
790
|
|
722
|
-
attach_function :amqp_consume_message, [ConnectionState,
|
723
|
-
attach_function :amqp_destroy_envelope, [
|
791
|
+
attach_function :amqp_consume_message, [ConnectionState, Envelope.ptr, Timeval.ptr, :int], RpcReply.by_value, **opts
|
792
|
+
attach_function :amqp_destroy_envelope, [Envelope.ptr], :void, **opts
|
724
793
|
|
725
794
|
class ConnectionInfo < ::FFI::Struct
|
726
795
|
layout :user, :string,
|
@@ -731,13 +800,23 @@ module RabbitMQ
|
|
731
800
|
:ssl, Boolean
|
732
801
|
end
|
733
802
|
|
734
|
-
attach_function :amqp_default_connection_info, [
|
735
|
-
attach_function :amqp_parse_url, [:
|
736
|
-
attach_function :amqp_socket_open, [:pointer, :string, :int],
|
737
|
-
attach_function :amqp_socket_open_noblock, [:pointer, :string, :int,
|
738
|
-
attach_function :amqp_socket_get_sockfd, [:pointer],
|
739
|
-
attach_function :amqp_get_socket, [ConnectionState],
|
740
|
-
attach_function :amqp_get_server_properties, [ConnectionState],
|
803
|
+
attach_function :amqp_default_connection_info, [ConnectionInfo.ptr], :void, **opts
|
804
|
+
attach_function :amqp_parse_url, [:pointer, ConnectionInfo.ptr], Status, **opts
|
805
|
+
attach_function :amqp_socket_open, [:pointer, :string, :int], Status, **opts
|
806
|
+
attach_function :amqp_socket_open_noblock, [:pointer, :string, :int, Timeval.ptr], Status, **opts
|
807
|
+
attach_function :amqp_socket_get_sockfd, [:pointer], :int, **opts
|
808
|
+
attach_function :amqp_get_socket, [ConnectionState], :pointer, **opts
|
809
|
+
attach_function :amqp_get_server_properties, [ConnectionState], Table, **opts
|
810
|
+
|
811
|
+
attach_function :amqp_tcp_socket_new, [ConnectionState], :pointer, **opts
|
812
|
+
attach_function :amqp_tcp_socket_set_sockfd, [:pointer, :int], :void, **opts
|
813
|
+
|
814
|
+
attach_function :amqp_ssl_socket_new, [ConnectionState], :pointer, **opts
|
815
|
+
attach_function :amqp_ssl_socket_set_cacert, [:pointer, :string], Status, **opts
|
816
|
+
attach_function :amqp_ssl_socket_set_key, [:pointer, :string, :string], Status, **opts
|
817
|
+
attach_function :amqp_ssl_socket_set_key_buffer, [:pointer, :string, :pointer, :size_t], Status, **opts
|
818
|
+
attach_function :amqp_ssl_socket_set_verify, [:pointer, Boolean], :void, **opts
|
819
|
+
attach_function :amqp_set_initialize_ssl_library, [Boolean], :void, **opts
|
741
820
|
end
|
742
821
|
end
|
743
822
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module RabbitMQ
|
3
|
+
module FFI
|
4
|
+
|
5
|
+
class Error < RuntimeError
|
6
|
+
def initialize message=nil
|
7
|
+
@message = message
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
if @message && status_message; "#{status_message} - #{@message}"
|
12
|
+
elsif @message; @message
|
13
|
+
elsif status_message; status_message
|
14
|
+
else; ""
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def status_message
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
@lookup_table = {}
|
23
|
+
class << self
|
24
|
+
attr_reader :lookup_table
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.lookup status
|
28
|
+
lookup_table.fetch(status)
|
29
|
+
end
|
30
|
+
|
31
|
+
FFI::Status.symbols.each do |status|
|
32
|
+
message = RabbitMQ::FFI.amqp_error_string2(status)
|
33
|
+
const_name = status.to_s.gsub(/((?:\A\w)|(?:_\w))/) { |x| x[-1].upcase }
|
34
|
+
|
35
|
+
kls = Class.new(Error) { define_method(:status_message) { message } }
|
36
|
+
lookup_table[status] = kls
|
37
|
+
const_set const_name, kls
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
module RabbitMQ
|
3
|
+
module FFI
|
4
|
+
|
5
|
+
class ConnectionInfo
|
6
|
+
def to_h
|
7
|
+
members.map { |k| [k, self[k]] }.to_h
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Bytes
|
12
|
+
def to_s
|
13
|
+
::FFI::Pointer.new(self[:bytes]).read_bytes(self[:len])
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_s(str)
|
17
|
+
size = str.bytesize
|
18
|
+
ptr = Util.mem_ptr(size, release: false)
|
19
|
+
ptr.write_string(str)
|
20
|
+
|
21
|
+
bytes = new
|
22
|
+
bytes[:len] = str.bytesize
|
23
|
+
bytes[:bytes] = Util.mem_ptr(str.bytesize, release: false)
|
24
|
+
bytes
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class FieldValue
|
29
|
+
private def value_member(kind)
|
30
|
+
case kind
|
31
|
+
when :utf8; :bytes
|
32
|
+
when :timestamp; :u64
|
33
|
+
else kind
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_value
|
38
|
+
kind = self[:kind]
|
39
|
+
value = self[:value][value_member(kind)]
|
40
|
+
case kind
|
41
|
+
when :bytes; value.to_s
|
42
|
+
when :utf8; value.to_s.force_encoding(Encoding::UTF_8)
|
43
|
+
when :timestamp; Time.at(value / 1000.0)
|
44
|
+
when :table; value.to_h
|
45
|
+
when :array; value.to_array_not_yet_implemented!
|
46
|
+
when :decimal; value.to_value_not_yet_implemented!
|
47
|
+
else value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Table
|
53
|
+
def to_h
|
54
|
+
entry_ptr = self[:entries]
|
55
|
+
entries = self[:num_entries].times.map { |i|
|
56
|
+
entry = FFI::TableEntry.new(entry_ptr + i * FFI::TableEntry.size)
|
57
|
+
[entry[:key].to_s, entry[:value].to_value]
|
58
|
+
}.to_h
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
class RabbitMQ::FFI::Error < RuntimeError; end
|
3
|
+
|
4
|
+
module RabbitMQ::Util
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def error_check action, status
|
8
|
+
return if status == :ok
|
9
|
+
raise RabbitMQ::FFI::Error.lookup(status), "while #{action}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def null_check action, obj
|
13
|
+
return unless obj.nil?
|
14
|
+
raise RabbitMQ::FFI::Error, "while #{action} - got unexpected null"
|
15
|
+
end
|
16
|
+
|
17
|
+
def mem_ptr size, count: 1, clear: true, release: true
|
18
|
+
ptr = ::FFI::MemoryPointer.new(size, count, clear)
|
19
|
+
ptr.autorelease = false unless release
|
20
|
+
ptr
|
21
|
+
end
|
22
|
+
|
23
|
+
def arg_ptr type, **kwargs
|
24
|
+
type = ::FFI::TypeDefs[type] if type.is_a?(Symbol)
|
25
|
+
mem_ptr(type.size, clear: false, **kwargs)
|
26
|
+
end
|
27
|
+
|
28
|
+
def strdup_ptr str, **kwargs
|
29
|
+
str = str + "\x00"
|
30
|
+
ptr = mem_ptr(str.bytesize, **kwargs)
|
31
|
+
ptr.write_string(str)
|
32
|
+
ptr
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rabbitmq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe McIlvain
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -111,12 +111,19 @@ dependencies:
|
|
111
111
|
description: A Ruby RabbitMQ client library based on FFI bindings for librabbitmq.
|
112
112
|
email: joe.eli.mac@gmail.com
|
113
113
|
executables: []
|
114
|
-
extensions:
|
114
|
+
extensions:
|
115
|
+
- ext/rabbitmq/Rakefile
|
115
116
|
extra_rdoc_files: []
|
116
117
|
files:
|
118
|
+
- LICENSE
|
117
119
|
- README.md
|
120
|
+
- ext/rabbitmq/Rakefile
|
118
121
|
- lib/rabbitmq.rb
|
122
|
+
- lib/rabbitmq/connection.rb
|
119
123
|
- lib/rabbitmq/ffi.rb
|
124
|
+
- lib/rabbitmq/ffi/error.rb
|
125
|
+
- lib/rabbitmq/ffi/ext.rb
|
126
|
+
- lib/rabbitmq/util.rb
|
120
127
|
homepage: https://github.com/jemc/rabbitmq/
|
121
128
|
licenses:
|
122
129
|
- MIT
|