rabbitmq 0.0.1 → 0.1.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/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
|