rabbitmq 0.1.1 → 0.2.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/ext/rabbitmq/Rakefile +1 -1
- data/lib/rabbitmq.rb +4 -1
- data/lib/rabbitmq/channel.rb +261 -0
- data/lib/rabbitmq/connection.rb +298 -30
- data/lib/rabbitmq/ffi.rb +110 -99
- data/lib/rabbitmq/ffi/error.rb +2 -4
- data/lib/rabbitmq/ffi/ext.rb +232 -23
- data/lib/rabbitmq/server_error.rb +62 -0
- data/lib/rabbitmq/util.rb +26 -9
- metadata +4 -2
data/lib/rabbitmq/ffi.rb
CHANGED
@@ -6,6 +6,7 @@ module RabbitMQ
|
|
6
6
|
module FFI
|
7
7
|
extend ::FFI::Library
|
8
8
|
|
9
|
+
ffi_lib ::FFI::Library::LIBC
|
9
10
|
ffi_lib \
|
10
11
|
File.expand_path("../../ext/rabbitmq/librabbitmq.so", File.dirname(__FILE__))
|
11
12
|
|
@@ -14,11 +15,45 @@ module RabbitMQ
|
|
14
15
|
blocking: true # only necessary on MRI to deal with the GIL.
|
15
16
|
}
|
16
17
|
|
17
|
-
|
18
|
+
attach_function :free, [:pointer], :void, **opts
|
19
|
+
attach_function :malloc, [:size_t], :pointer, **opts
|
18
20
|
|
19
21
|
attach_function :amqp_version_number, [], :uint32, **opts
|
20
22
|
attach_function :amqp_version, [], :string, **opts
|
21
23
|
|
24
|
+
Status = enum ::FFI::TypeDefs[:int], [
|
25
|
+
:ok, 0x0,
|
26
|
+
:no_memory, -0x0001,
|
27
|
+
:bad_amqp_data, -0x0002,
|
28
|
+
:unknown_class, -0x0003,
|
29
|
+
:unknown_method, -0x0004,
|
30
|
+
:hostname_resolution_failed, -0x0005,
|
31
|
+
:incompatible_amqp_version, -0x0006,
|
32
|
+
:connection_closed, -0x0007,
|
33
|
+
:bad_url, -0x0008,
|
34
|
+
:socket_error, -0x0009,
|
35
|
+
:invalid_parameter, -0x000A,
|
36
|
+
:table_too_big, -0x000B,
|
37
|
+
:wrong_method, -0x000C,
|
38
|
+
:timeout, -0x000D,
|
39
|
+
:timer_failure, -0x000E,
|
40
|
+
:heartbeat_timeout, -0x000F,
|
41
|
+
:unexpected_state, -0x0010,
|
42
|
+
:unexpected_socket_closed, -0x0011,
|
43
|
+
:unexpected_socket_inuse, -0x0012,
|
44
|
+
:tcp_error, -0x0100,
|
45
|
+
:tcp_socketlib_init_error, -0x0101,
|
46
|
+
:ssl_error, -0x0200,
|
47
|
+
:ssl_hostname_verify_failed, -0x0201,
|
48
|
+
:ssl_peer_verify_failed, -0x0202,
|
49
|
+
:ssl_connection_failed, -0x0203,
|
50
|
+
]
|
51
|
+
|
52
|
+
DeliveryMode = enum ::FFI::TypeDefs[:uint8], [
|
53
|
+
:nonpersistent, 1,
|
54
|
+
:persistent, 2,
|
55
|
+
]
|
56
|
+
|
22
57
|
class Timeval < ::FFI::Struct
|
23
58
|
layout :tv_sec, :time_t,
|
24
59
|
:tv_usec, :suseconds_t
|
@@ -98,8 +133,10 @@ module RabbitMQ
|
|
98
133
|
:confirm_select_ok, 0x0055000B, # 85, 11; 5570571
|
99
134
|
]
|
100
135
|
|
101
|
-
Flags
|
102
|
-
|
136
|
+
Flags = :uint32
|
137
|
+
|
138
|
+
Channel = ::FFI::TypeDefs[:uint16]
|
139
|
+
CHANNEL_MAX_ID = 2 ** (Channel.size * 8) - 1
|
103
140
|
|
104
141
|
class Bytes < ::FFI::Struct
|
105
142
|
layout :len, :size_t,
|
@@ -189,6 +226,13 @@ module RabbitMQ
|
|
189
226
|
:decoded, :pointer
|
190
227
|
end
|
191
228
|
|
229
|
+
FrameType = enum ::FFI::TypeDefs[:uint8], [
|
230
|
+
:method, 1,
|
231
|
+
:header, 2,
|
232
|
+
:body, 3,
|
233
|
+
:heartbeat, 8,
|
234
|
+
]
|
235
|
+
|
192
236
|
class FramePayloadProperties < ::FFI::Struct
|
193
237
|
layout :class_id, :uint16,
|
194
238
|
:body_size, :uint64,
|
@@ -210,8 +254,8 @@ module RabbitMQ
|
|
210
254
|
:protocol_header, FramePayloadProtocolHeader
|
211
255
|
end
|
212
256
|
|
213
|
-
class Frame < ::FFI::
|
214
|
-
layout :frame_type,
|
257
|
+
class Frame < ::FFI::Struct
|
258
|
+
layout :frame_type, FrameType,
|
215
259
|
:channel, Channel,
|
216
260
|
:payload, FramePayload
|
217
261
|
end
|
@@ -226,7 +270,7 @@ module RabbitMQ
|
|
226
270
|
class RpcReply < ::FFI::Struct
|
227
271
|
layout :reply_type, ResponseType,
|
228
272
|
:reply, Method,
|
229
|
-
:library_error,
|
273
|
+
:library_error, Status
|
230
274
|
end
|
231
275
|
|
232
276
|
SaslMethod = enum [
|
@@ -235,48 +279,15 @@ module RabbitMQ
|
|
235
279
|
|
236
280
|
ConnectionState = :pointer
|
237
281
|
|
238
|
-
Status = enum [
|
239
|
-
:ok, 0x0,
|
240
|
-
:no_memory, -0x0001,
|
241
|
-
:bad_amqp_data, -0x0002,
|
242
|
-
:unknown_class, -0x0003,
|
243
|
-
:unknown_method, -0x0004,
|
244
|
-
:hostname_resolution_failed, -0x0005,
|
245
|
-
:incompatible_amqp_version, -0x0006,
|
246
|
-
:connection_closed, -0x0007,
|
247
|
-
:bad_url, -0x0008,
|
248
|
-
:socket_error, -0x0009,
|
249
|
-
:invalid_parameter, -0x000A,
|
250
|
-
:table_too_big, -0x000B,
|
251
|
-
:wrong_method, -0x000C,
|
252
|
-
:timeout, -0x000D,
|
253
|
-
:timer_failure, -0x000E,
|
254
|
-
:heartbeat_timeout, -0x000F,
|
255
|
-
:unexpected_state, -0x0010,
|
256
|
-
:unexpected_socket_closed, -0x0011,
|
257
|
-
:unexpected_socket_inuse, -0x0012,
|
258
|
-
:tcp_error, -0x0100,
|
259
|
-
:tcp_socketlib_init_error, -0x0101,
|
260
|
-
:ssl_error, -0x0200,
|
261
|
-
:ssl_hostname_verify_failed, -0x0201,
|
262
|
-
:ssl_peer_verify_failed, -0x0202,
|
263
|
-
:ssl_connection_failed, -0x0203,
|
264
|
-
]
|
265
|
-
|
266
|
-
DeliveryMode = enum [
|
267
|
-
:nonpersistent, 1,
|
268
|
-
:persistent, 2,
|
269
|
-
]
|
270
|
-
|
271
282
|
attach_function :amqp_constant_name, [:int], :string, **opts
|
272
283
|
attach_function :amqp_constant_is_hard_error, [:int], Boolean, **opts
|
273
284
|
|
274
|
-
attach_function :amqp_method_name, [MethodNumber],
|
275
|
-
attach_function :amqp_method_has_content, [MethodNumber],
|
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
|
285
|
+
attach_function :amqp_method_name, [MethodNumber], :string, **opts
|
286
|
+
attach_function :amqp_method_has_content, [MethodNumber], Boolean, **opts
|
287
|
+
attach_function :amqp_decode_method, [MethodNumber, Pool.ptr, Bytes.val, :pointer], Status, **opts
|
288
|
+
attach_function :amqp_decode_properties, [:uint16, Pool.ptr, Bytes.val, :pointer], Status, **opts
|
289
|
+
attach_function :amqp_encode_method, [MethodNumber, :pointer, Bytes.val], Status, **opts
|
290
|
+
attach_function :amqp_encode_properties, [:uint16, :pointer, Bytes.val], Status, **opts
|
280
291
|
|
281
292
|
class ConnectionStart < ::FFI::Struct
|
282
293
|
layout :version_major, :uint8,
|
@@ -362,7 +373,7 @@ module RabbitMQ
|
|
362
373
|
layout :reply_code, :uint16,
|
363
374
|
:reply_text, Bytes,
|
364
375
|
:class_id, :uint16,
|
365
|
-
:
|
376
|
+
:method_id, :uint16
|
366
377
|
end
|
367
378
|
|
368
379
|
class ChannelCloseOk < ::FFI::Struct
|
@@ -391,7 +402,7 @@ module RabbitMQ
|
|
391
402
|
:auto_delete, Boolean,
|
392
403
|
:internal, Boolean,
|
393
404
|
:nowait, Boolean,
|
394
|
-
:arguments,
|
405
|
+
:arguments, Table
|
395
406
|
end
|
396
407
|
|
397
408
|
class ExchangeDeclareOk < ::FFI::Struct
|
@@ -415,7 +426,7 @@ module RabbitMQ
|
|
415
426
|
:source, Bytes,
|
416
427
|
:routing_key, Bytes,
|
417
428
|
:nowait, Boolean,
|
418
|
-
:arguments,
|
429
|
+
:arguments, Table
|
419
430
|
end
|
420
431
|
|
421
432
|
class ExchangeBindOk < ::FFI::Struct
|
@@ -428,7 +439,7 @@ module RabbitMQ
|
|
428
439
|
:source, Bytes,
|
429
440
|
:routing_key, Bytes,
|
430
441
|
:nowait, Boolean,
|
431
|
-
:arguments,
|
442
|
+
:arguments, Table
|
432
443
|
end
|
433
444
|
|
434
445
|
class ExchangeUnbindOk < ::FFI::Struct
|
@@ -443,7 +454,7 @@ module RabbitMQ
|
|
443
454
|
:exclusive, Boolean,
|
444
455
|
:auto_delete, Boolean,
|
445
456
|
:nowait, Boolean,
|
446
|
-
:arguments,
|
457
|
+
:arguments, Table
|
447
458
|
end
|
448
459
|
|
449
460
|
class QueueDeclareOk < ::FFI::Struct
|
@@ -458,7 +469,7 @@ module RabbitMQ
|
|
458
469
|
:exchange, Bytes,
|
459
470
|
:routing_key, Bytes,
|
460
471
|
:nowait, Boolean,
|
461
|
-
:arguments,
|
472
|
+
:arguments, Table
|
462
473
|
end
|
463
474
|
|
464
475
|
class QueueBindOk < ::FFI::Struct
|
@@ -492,7 +503,7 @@ module RabbitMQ
|
|
492
503
|
:queue, Bytes,
|
493
504
|
:exchange, Bytes,
|
494
505
|
:routing_key, Bytes,
|
495
|
-
:arguments,
|
506
|
+
:arguments, Table
|
496
507
|
end
|
497
508
|
|
498
509
|
class QueueUnbindOk < ::FFI::Struct
|
@@ -517,7 +528,7 @@ module RabbitMQ
|
|
517
528
|
:no_ack, Boolean,
|
518
529
|
:exclusive, Boolean,
|
519
530
|
:nowait, Boolean,
|
520
|
-
:arguments,
|
531
|
+
:arguments, Table
|
521
532
|
end
|
522
533
|
|
523
534
|
class BasicConsumeOk < ::FFI::Struct
|
@@ -674,7 +685,7 @@ module RabbitMQ
|
|
674
685
|
:content_type, Bytes,
|
675
686
|
:content_encoding, Bytes,
|
676
687
|
:headers, Table,
|
677
|
-
:delivery_mode,
|
688
|
+
:delivery_mode, DeliveryMode,
|
678
689
|
:priority, :uint8,
|
679
690
|
:correlation_id, Bytes,
|
680
691
|
:reply_to, Bytes,
|
@@ -687,25 +698,25 @@ module RabbitMQ
|
|
687
698
|
:cluster_id, Bytes
|
688
699
|
end
|
689
700
|
|
690
|
-
attach_function :amqp_channel_open, [ConnectionState, Channel],
|
691
|
-
attach_function :amqp_channel_flow, [ConnectionState, Channel, Boolean],
|
692
|
-
attach_function :amqp_exchange_declare, [ConnectionState, Channel, Bytes, Bytes, Boolean, Boolean, Table],
|
693
|
-
attach_function :amqp_exchange_delete, [ConnectionState, Channel, Bytes, Boolean],
|
694
|
-
attach_function :amqp_exchange_bind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table],
|
695
|
-
attach_function :amqp_exchange_unbind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table],
|
696
|
-
attach_function :amqp_queue_declare, [ConnectionState, Channel, Bytes, Boolean, Boolean, Boolean, Boolean, Table],
|
697
|
-
attach_function :amqp_queue_bind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table],
|
698
|
-
attach_function :amqp_queue_purge, [ConnectionState, Channel, Bytes],
|
699
|
-
attach_function :amqp_queue_delete, [ConnectionState, Channel, Bytes, Boolean, Boolean],
|
700
|
-
attach_function :amqp_queue_unbind, [ConnectionState, Channel, Bytes, Bytes, Bytes, Table],
|
701
|
-
attach_function :amqp_basic_qos, [ConnectionState, Channel, :uint32, :uint16, Boolean],
|
702
|
-
attach_function :amqp_basic_consume, [ConnectionState, Channel, Bytes, Bytes, Boolean, Boolean, Boolean, Table],
|
703
|
-
attach_function :amqp_basic_cancel, [ConnectionState, Channel, Bytes],
|
704
|
-
attach_function :amqp_basic_recover, [ConnectionState, Channel, Boolean],
|
705
|
-
attach_function :amqp_tx_select, [ConnectionState, Channel],
|
706
|
-
attach_function :amqp_tx_commit, [ConnectionState, Channel],
|
707
|
-
attach_function :amqp_tx_rollback, [ConnectionState, Channel],
|
708
|
-
attach_function :amqp_confirm_select, [ConnectionState, Channel],
|
701
|
+
attach_function :amqp_channel_open, [ConnectionState, Channel], ChannelOpenOk.ptr, **opts
|
702
|
+
attach_function :amqp_channel_flow, [ConnectionState, Channel, Boolean], ChannelFlowOk.ptr, **opts
|
703
|
+
attach_function :amqp_exchange_declare, [ConnectionState, Channel, Bytes.val, Bytes.val, Boolean, Boolean, Table.val], ExchangeDeclareOk.ptr, **opts
|
704
|
+
attach_function :amqp_exchange_delete, [ConnectionState, Channel, Bytes.val, Boolean], ExchangeDeleteOk.ptr, **opts
|
705
|
+
attach_function :amqp_exchange_bind, [ConnectionState, Channel, Bytes.val, Bytes.val, Bytes.val, Table.val], ExchangeBindOk.ptr, **opts
|
706
|
+
attach_function :amqp_exchange_unbind, [ConnectionState, Channel, Bytes.val, Bytes.val, Bytes.val, Table.val], ExchangeUnbindOk.ptr, **opts
|
707
|
+
attach_function :amqp_queue_declare, [ConnectionState, Channel, Bytes.val, Boolean, Boolean, Boolean, Boolean, Table.val], QueueDeclareOk.ptr, **opts
|
708
|
+
attach_function :amqp_queue_bind, [ConnectionState, Channel, Bytes.val, Bytes.val, Bytes.val, Table.val], QueueBindOk.ptr, **opts
|
709
|
+
attach_function :amqp_queue_purge, [ConnectionState, Channel, Bytes.val], QueuePurgeOk.ptr, **opts
|
710
|
+
attach_function :amqp_queue_delete, [ConnectionState, Channel, Bytes.val, Boolean, Boolean], QueueDeleteOk.ptr, **opts
|
711
|
+
attach_function :amqp_queue_unbind, [ConnectionState, Channel, Bytes.val, Bytes.val, Bytes.val, Table.val], QueueUnbindOk.ptr, **opts
|
712
|
+
attach_function :amqp_basic_qos, [ConnectionState, Channel, :uint32, :uint16, Boolean], BasicQosOk.ptr, **opts
|
713
|
+
attach_function :amqp_basic_consume, [ConnectionState, Channel, Bytes.val, Bytes.val, Boolean, Boolean, Boolean, Table.val], BasicConsumeOk.ptr, **opts
|
714
|
+
attach_function :amqp_basic_cancel, [ConnectionState, Channel, Bytes.val], BasicCancelOk.ptr, **opts
|
715
|
+
attach_function :amqp_basic_recover, [ConnectionState, Channel, Boolean], BasicRecoverOk.ptr, **opts
|
716
|
+
attach_function :amqp_tx_select, [ConnectionState, Channel], TxSelect.ptr, **opts
|
717
|
+
attach_function :amqp_tx_commit, [ConnectionState, Channel], TxCommit.ptr, **opts
|
718
|
+
attach_function :amqp_tx_rollback, [ConnectionState, Channel], TxRollback.ptr, **opts
|
719
|
+
attach_function :amqp_confirm_select, [ConnectionState, Channel], ConfirmSelect.ptr, **opts
|
709
720
|
|
710
721
|
attach_function :init_amqp_pool, [Pool.ptr, :size_t], :void, **opts
|
711
722
|
attach_function :recycle_amqp_pool, [Pool.ptr], :void, **opts
|
@@ -713,10 +724,10 @@ module RabbitMQ
|
|
713
724
|
attach_function :amqp_pool_alloc, [Pool.ptr, :size_t], :pointer, **opts
|
714
725
|
attach_function :amqp_pool_alloc_bytes, [Pool.ptr, :size_t, Bytes.ptr], :void, **opts
|
715
726
|
|
716
|
-
attach_function :amqp_cstring_bytes, [:string],
|
717
|
-
attach_function :amqp_bytes_malloc_dup, [Bytes], Bytes, **opts
|
718
|
-
attach_function :amqp_bytes_malloc, [:size_t],
|
719
|
-
attach_function :amqp_bytes_free, [Bytes], :void,
|
727
|
+
attach_function :amqp_cstring_bytes, [:string], Bytes.val, **opts
|
728
|
+
attach_function :amqp_bytes_malloc_dup, [Bytes.val], Bytes.val, **opts
|
729
|
+
attach_function :amqp_bytes_malloc, [:size_t], Bytes.val, **opts
|
730
|
+
attach_function :amqp_bytes_free, [Bytes.val], :void, **opts
|
720
731
|
|
721
732
|
attach_function :amqp_new_connection, [], ConnectionState, **opts
|
722
733
|
attach_function :amqp_get_sockfd, [ConnectionState], :int, **opts
|
@@ -727,12 +738,12 @@ module RabbitMQ
|
|
727
738
|
attach_function :amqp_get_heartbeat, [ConnectionState], :int, **opts
|
728
739
|
attach_function :amqp_destroy_connection, [ConnectionState], Status, **opts
|
729
740
|
|
730
|
-
attach_function :amqp_handle_input, [ConnectionState, Bytes, Frame.ptr], Status, **opts
|
731
|
-
attach_function :amqp_release_buffers_ok, [ConnectionState],
|
732
|
-
attach_function :amqp_release_buffers, [ConnectionState],
|
733
|
-
attach_function :amqp_maybe_release_buffers, [ConnectionState],
|
734
|
-
attach_function :amqp_maybe_release_buffers_on_channel, [ConnectionState, Channel],
|
735
|
-
attach_function :amqp_send_frame, [ConnectionState, Frame.ptr],
|
741
|
+
attach_function :amqp_handle_input, [ConnectionState, Bytes.val, Frame.ptr], Status, **opts
|
742
|
+
attach_function :amqp_release_buffers_ok, [ConnectionState], Boolean, **opts
|
743
|
+
attach_function :amqp_release_buffers, [ConnectionState], :void, **opts
|
744
|
+
attach_function :amqp_maybe_release_buffers, [ConnectionState], :void, **opts
|
745
|
+
attach_function :amqp_maybe_release_buffers_on_channel, [ConnectionState, Channel], :void, **opts
|
746
|
+
attach_function :amqp_send_frame, [ConnectionState, Frame.ptr], Status, **opts
|
736
747
|
|
737
748
|
attach_function :amqp_table_entry_cmp, [:pointer, :pointer], :int, **opts
|
738
749
|
|
@@ -743,19 +754,19 @@ module RabbitMQ
|
|
743
754
|
attach_function :amqp_simple_wait_frame, [ConnectionState, Frame.ptr], Status, **opts
|
744
755
|
attach_function :amqp_simple_wait_frame_noblock, [ConnectionState, Frame.ptr, Timeval.ptr], Status, **opts
|
745
756
|
attach_function :amqp_simple_wait_method, [ConnectionState, Channel, MethodNumber, Method.ptr], Status, **opts
|
746
|
-
attach_function :amqp_send_method, [ConnectionState, Channel, MethodNumber,
|
757
|
+
attach_function :amqp_send_method, [ConnectionState, Channel, MethodNumber, :pointer], Status, **opts
|
747
758
|
|
748
|
-
attach_function :amqp_simple_rpc, [ConnectionState, Channel, MethodNumber, :pointer, :pointer], RpcReply.
|
749
|
-
attach_function :amqp_simple_rpc_decoded, [ConnectionState, Channel, MethodNumber, MethodNumber, :pointer], :pointer,
|
750
|
-
attach_function :amqp_get_rpc_reply, [ConnectionState], RpcReply.
|
751
|
-
attach_function :amqp_login, [ConnectionState, :string, :int, :int, :int, SaslMethod, :varargs], RpcReply.
|
752
|
-
attach_function :amqp_login_with_properties, [ConnectionState, :string, :int, :int, :int, Table.ptr, SaslMethod, :varargs], RpcReply.
|
753
|
-
attach_function :amqp_channel_close, [ConnectionState, Channel, :int], RpcReply.
|
754
|
-
attach_function :amqp_connection_close, [ConnectionState, :int], RpcReply.
|
759
|
+
attach_function :amqp_simple_rpc, [ConnectionState, Channel, MethodNumber, :pointer, :pointer], RpcReply.val, **opts
|
760
|
+
attach_function :amqp_simple_rpc_decoded, [ConnectionState, Channel, MethodNumber, MethodNumber, :pointer], :pointer, **opts
|
761
|
+
attach_function :amqp_get_rpc_reply, [ConnectionState], RpcReply.val, **opts
|
762
|
+
attach_function :amqp_login, [ConnectionState, :string, :int, :int, :int, SaslMethod, :varargs], RpcReply.val, **opts
|
763
|
+
attach_function :amqp_login_with_properties, [ConnectionState, :string, :int, :int, :int, Table.ptr, SaslMethod, :varargs], RpcReply.val, **opts
|
764
|
+
attach_function :amqp_channel_close, [ConnectionState, Channel, :int], RpcReply.val, **opts
|
765
|
+
attach_function :amqp_connection_close, [ConnectionState, :int], RpcReply.val, **opts
|
755
766
|
|
756
|
-
attach_function :amqp_basic_publish, [ConnectionState, Channel, Bytes, Bytes, Boolean, Boolean, BasicProperties.ptr, Bytes],
|
767
|
+
attach_function :amqp_basic_publish, [ConnectionState, Channel, Bytes.val, Bytes.val, Boolean, Boolean, BasicProperties.ptr, Bytes.val], Status, **opts
|
757
768
|
|
758
|
-
attach_function :amqp_basic_get, [ConnectionState, Channel, Bytes, Boolean],
|
769
|
+
attach_function :amqp_basic_get, [ConnectionState, Channel, Bytes.val, Boolean], Status, **opts
|
759
770
|
attach_function :amqp_basic_ack, [ConnectionState, Channel, :uint64, Boolean], Status, **opts
|
760
771
|
attach_function :amqp_basic_reject, [ConnectionState, Channel, :uint64, Boolean], Status, **opts
|
761
772
|
attach_function :amqp_basic_nack, [ConnectionState, Channel, :uint64, Boolean, Boolean], Status, **opts
|
@@ -765,8 +776,8 @@ module RabbitMQ
|
|
765
776
|
attach_function :amqp_error_string, [:int], :string, **opts
|
766
777
|
attach_function :amqp_error_string2, [:int], :string, **opts
|
767
778
|
|
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
|
779
|
+
attach_function :amqp_decode_table, [Bytes.val, Pool.ptr, Table.ptr, :pointer], Status, **opts
|
780
|
+
attach_function :amqp_encode_table, [Bytes.val, Table.ptr, :pointer], Status, **opts
|
770
781
|
attach_function :amqp_table_clone, [Table.ptr, Table.ptr, Pool.ptr], Status, **opts
|
771
782
|
|
772
783
|
class Message < ::FFI::Struct
|
@@ -775,8 +786,8 @@ module RabbitMQ
|
|
775
786
|
:pool, Pool
|
776
787
|
end
|
777
788
|
|
778
|
-
attach_function :amqp_read_message, [ConnectionState, Channel, Message.ptr, :int], RpcReply.
|
779
|
-
attach_function :amqp_destroy_message, [Message.ptr], :void,
|
789
|
+
attach_function :amqp_read_message, [ConnectionState, Channel, Message.ptr, :int], RpcReply.val, **opts
|
790
|
+
attach_function :amqp_destroy_message, [Message.ptr], :void, **opts
|
780
791
|
|
781
792
|
class Envelope < ::FFI::Struct
|
782
793
|
layout :channel, Channel,
|
@@ -788,8 +799,8 @@ module RabbitMQ
|
|
788
799
|
:message, Message
|
789
800
|
end
|
790
801
|
|
791
|
-
attach_function :amqp_consume_message, [ConnectionState, Envelope.ptr, Timeval.ptr, :int], RpcReply.
|
792
|
-
attach_function :amqp_destroy_envelope, [Envelope.ptr], :void,
|
802
|
+
attach_function :amqp_consume_message, [ConnectionState, Envelope.ptr, Timeval.ptr, :int], RpcReply.val, **opts
|
803
|
+
attach_function :amqp_destroy_envelope, [Envelope.ptr], :void, **opts
|
793
804
|
|
794
805
|
class ConnectionInfo < ::FFI::Struct
|
795
806
|
layout :user, :string,
|
data/lib/rabbitmq/ffi/error.rb
CHANGED
@@ -29,12 +29,10 @@ module RabbitMQ
|
|
29
29
|
end
|
30
30
|
|
31
31
|
FFI::Status.symbols.each do |status|
|
32
|
-
message
|
33
|
-
const_name = status.to_s.gsub(/((?:\A\w)|(?:_\w))/) { |x| x[-1].upcase }
|
34
|
-
|
32
|
+
message = RabbitMQ::FFI.amqp_error_string2(status)
|
35
33
|
kls = Class.new(Error) { define_method(:status_message) { message } }
|
36
34
|
lookup_table[status] = kls
|
37
|
-
const_set const_name, kls
|
35
|
+
const_set Util.const_name(status), kls
|
38
36
|
end
|
39
37
|
end
|
40
38
|
|
data/lib/rabbitmq/ffi/ext.rb
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
module RabbitMQ
|
3
3
|
module FFI
|
4
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
|
+
|
5
17
|
class ConnectionInfo
|
6
18
|
def to_h
|
7
19
|
members.map { |k| [k, self[k]] }.to_h
|
@@ -9,19 +21,29 @@ module RabbitMQ
|
|
9
21
|
end
|
10
22
|
|
11
23
|
class Bytes
|
12
|
-
def to_s
|
13
|
-
|
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
|
14
29
|
end
|
15
30
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
31
|
+
def free!
|
32
|
+
FFI.free(self[:bytes])
|
33
|
+
clear
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.from_s(str, borrow=false)
|
37
|
+
if borrow
|
38
|
+
FFI.amqp_cstring_bytes(str)
|
39
|
+
else
|
40
|
+
size = str.bytesize
|
41
|
+
bytes = FFI.amqp_bytes_malloc(size)
|
42
|
+
|
43
|
+
bytes[:bytes].write_string(str)
|
44
|
+
bytes[:len] = size
|
45
|
+
bytes
|
46
|
+
end
|
25
47
|
end
|
26
48
|
end
|
27
49
|
|
@@ -34,28 +56,215 @@ module RabbitMQ
|
|
34
56
|
end
|
35
57
|
end
|
36
58
|
|
37
|
-
def to_value
|
38
|
-
kind
|
39
|
-
value
|
40
|
-
case kind
|
41
|
-
when :bytes; value.to_s
|
42
|
-
when :utf8; value.to_s.force_encoding(Encoding::UTF_8)
|
59
|
+
def to_value(free=false)
|
60
|
+
kind = self[:kind]
|
61
|
+
value = self[:value][value_member(kind)]
|
62
|
+
result = case kind
|
63
|
+
when :bytes; value.to_s(free)
|
64
|
+
when :utf8; value.to_s(free).force_encoding(Encoding::UTF_8)
|
43
65
|
when :timestamp; Time.at(value / 1000.0)
|
44
|
-
when :table; value.to_h
|
66
|
+
when :table; value.to_h(free)
|
45
67
|
when :array; value.to_array_not_yet_implemented!
|
46
68
|
when :decimal; value.to_value_not_yet_implemented!
|
47
69
|
else value
|
48
70
|
end
|
71
|
+
|
72
|
+
clear if free
|
73
|
+
result
|
74
|
+
end
|
75
|
+
|
76
|
+
def free!
|
77
|
+
kind = self[:kind]
|
78
|
+
value = self[:value][value_member(kind)]
|
79
|
+
value.free! if value.respond_to? :free!
|
80
|
+
clear
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.from(value, borrow=false)
|
84
|
+
obj = new
|
85
|
+
obj[:kind], obj[:value] = case value
|
86
|
+
when String; [:bytes, FieldValueValue.new(Bytes.from_s(value, borrow).pointer)]
|
87
|
+
else raise NotImplementedError
|
88
|
+
end
|
89
|
+
obj
|
49
90
|
end
|
50
91
|
end
|
51
92
|
|
52
93
|
class Table
|
53
|
-
|
94
|
+
include Enumerable
|
95
|
+
|
96
|
+
def each(*a, &b)
|
54
97
|
entry_ptr = self[:entries]
|
55
|
-
entries = self[:num_entries].times.map
|
56
|
-
|
57
|
-
|
58
|
-
|
98
|
+
entries = self[:num_entries].times.map do |i|
|
99
|
+
FFI::TableEntry.new(entry_ptr + i * FFI::TableEntry.size)
|
100
|
+
end
|
101
|
+
entries.each(*a, &b)
|
102
|
+
end
|
103
|
+
|
104
|
+
def to_h(free=false)
|
105
|
+
result = self.map do |entry|
|
106
|
+
[entry[:key].to_s(free), entry[:value].to_value(free)]
|
107
|
+
end.to_h
|
108
|
+
|
109
|
+
clear if free
|
110
|
+
result
|
111
|
+
end
|
112
|
+
|
113
|
+
def free!
|
114
|
+
self.each do
|
115
|
+
entry[:key].free!
|
116
|
+
entry[:value].free!
|
117
|
+
end
|
118
|
+
FFI.free(self[:entries])
|
119
|
+
clear
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.from(params, borrow=false)
|
123
|
+
size = params.size
|
124
|
+
entry_ptr = Util.mem_ptr(size * FFI::TableEntry.size, release: false)
|
125
|
+
params.each_with_index do |param, idx|
|
126
|
+
entry = FFI::TableEntry.new(entry_ptr + idx * FFI::TableEntry.size)
|
127
|
+
entry[:key] = FFI::Bytes.from_s(param.first.to_s, borrow)
|
128
|
+
entry[:value] = FFI::FieldValue.from(param.last, borrow)
|
129
|
+
end
|
130
|
+
|
131
|
+
obj = new
|
132
|
+
obj[:num_entries] = size
|
133
|
+
obj[:entries] = entry_ptr
|
134
|
+
obj
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class Method
|
139
|
+
MethodClasses = FFI::MethodNumber.symbols.map do |name|
|
140
|
+
const_name = name.to_s.gsub(/((?:\A\w)|(?:_\w))/) { |x| x[-1].upcase }
|
141
|
+
[name, FFI.const_get(const_name)]
|
142
|
+
end.to_h.freeze
|
143
|
+
|
144
|
+
MethodNames = MethodClasses.to_a.map(&:reverse).to_h.freeze
|
145
|
+
|
146
|
+
def to_h(free=false)
|
147
|
+
{ method: self[:id],
|
148
|
+
properties: self.decoded.to_h(free) }
|
149
|
+
end
|
150
|
+
|
151
|
+
def decoded
|
152
|
+
MethodClasses.fetch(self[:id]).new(self[:decoded])
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.lookup(kls)
|
156
|
+
MethodNames.fetch(kls)
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.lookup_class(name)
|
160
|
+
MethodClasses.fetch(name)
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.from(decoded)
|
164
|
+
obj = new
|
165
|
+
obj[:id] = lookup(decoded.class)
|
166
|
+
obj[:decoded] = decoded.pointer
|
167
|
+
obj
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.has_content?(type)
|
171
|
+
case type
|
172
|
+
when :basic_publish; true
|
173
|
+
when :basic_return; true
|
174
|
+
when :basic_deliver; true
|
175
|
+
when :basic_get_ok; true
|
176
|
+
else false
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
module MethodClassMixin
|
182
|
+
def apply(borrow=false, **params)
|
183
|
+
params.each do |key, value|
|
184
|
+
next if key == :dummy
|
185
|
+
case value
|
186
|
+
when String; value = FFI::Bytes.from_s(value, borrow)
|
187
|
+
when Hash; value = FFI::Table.from(value, borrow)
|
188
|
+
end
|
189
|
+
self[key] = value
|
190
|
+
end
|
191
|
+
self
|
192
|
+
end
|
193
|
+
|
194
|
+
def to_h(free=false)
|
195
|
+
result = {}
|
196
|
+
self.members.each do |key| [key, self[key]]
|
197
|
+
next if key == :dummy
|
198
|
+
value = self[key]
|
199
|
+
case value
|
200
|
+
when FFI::Bytes; value = value.to_s(free)
|
201
|
+
when FFI::Table; value = value.to_h(free)
|
202
|
+
end
|
203
|
+
result[key] = value
|
204
|
+
end
|
205
|
+
|
206
|
+
# TODO: handle the inverse case of this transformation in apply method
|
207
|
+
if (method_id = result.delete(:method_id))
|
208
|
+
method_num = (result.delete(:class_id) << 16) + method_id
|
209
|
+
result[:method] = FFI::MethodNumber[method_num]
|
210
|
+
end
|
211
|
+
|
212
|
+
clear if free
|
213
|
+
result
|
214
|
+
end
|
215
|
+
|
216
|
+
def free!
|
217
|
+
self.values.each do |item|
|
218
|
+
item.free! if item.respond_to? :free!
|
219
|
+
end
|
220
|
+
clear
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
Method::MethodClasses.each { |_, kls| kls.send(:include, MethodClassMixin) }
|
225
|
+
|
226
|
+
BasicProperties.send(:include, MethodClassMixin)
|
227
|
+
|
228
|
+
class FramePayloadProperties
|
229
|
+
def decoded
|
230
|
+
BasicProperties.new(self[:decoded])
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
class Frame
|
235
|
+
def payload
|
236
|
+
member = case self[:frame_type]
|
237
|
+
when :method; :method
|
238
|
+
when :header; :properties
|
239
|
+
when :body; :body_fragment
|
240
|
+
else; raise NotImplementedError, "frame type: #{self[:frame_type]}"
|
241
|
+
end
|
242
|
+
self[:payload][member]
|
243
|
+
end
|
244
|
+
|
245
|
+
def as_method_to_h(free=false)
|
246
|
+
# TODO: raise correct error class with enough info for appropriate action
|
247
|
+
raise "Wrong frame type for method frame of event: #{self[:frame_type]}" \
|
248
|
+
unless self[:frame_type] == :method
|
249
|
+
|
250
|
+
payload.to_h(free).merge(channel: self[:channel])
|
251
|
+
end
|
252
|
+
|
253
|
+
def as_header_to_h(free=false)
|
254
|
+
# TODO: raise correct error class with enough info for appropriate action
|
255
|
+
raise "Wrong frame type for header frame of multiframe event: #{self[:frame_type]}" \
|
256
|
+
unless self[:frame_type] == :header
|
257
|
+
|
258
|
+
properties = self[:payload][:properties]
|
259
|
+
{ header: properties.decoded.to_h(free), body_size: properties[:body_size] }
|
260
|
+
end
|
261
|
+
|
262
|
+
def as_body_to_s(free=false)
|
263
|
+
# TODO: raise correct error class with enough info for appropriate action
|
264
|
+
raise "Wrong frame type for body frame of multiframe event: #{self[:frame_type]}" \
|
265
|
+
unless self[:frame_type] == :body
|
266
|
+
|
267
|
+
self[:payload][:body_fragment].to_s(free)
|
59
268
|
end
|
60
269
|
end
|
61
270
|
|