amqp-client 0.2.2 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,41 +2,45 @@
2
2
 
3
3
  module AMQP
4
4
  class Client
5
- class Error < StandardError; end
6
-
7
- # Raised when a frame that wasn't expected arrives
8
- class UnexpectedFrame < Error
9
- def initialize(expected, actual)
10
- super "Expected frame type '#{expected}' but got '#{actual}'"
5
+ # All errors raised inherit from this class
6
+ class Error < StandardError
7
+ # Raised when a frame that wasn't expected arrives
8
+ class UnexpectedFrame < Error
9
+ def initialize(expected, actual)
10
+ super "Expected frame type '#{expected}' but got '#{actual}'"
11
+ end
11
12
  end
12
- end
13
13
 
14
- # Raised when a frame doesn't end with 206
15
- class UnexpectedFrameEnd < Error
16
- def initialize(actual)
17
- super "Expected frame end 206 but got '#{actual}'"
14
+ # Raised when a frame doesn't end with 206
15
+ class UnexpectedFrameEnd < Error
16
+ def initialize(actual)
17
+ super "Expected frame end 206 but got '#{actual}'"
18
+ end
18
19
  end
19
- end
20
20
 
21
- # Should never be raised as we support all offical frame types
22
- class UnsupportedFrameType < Error
23
- def initialize(type)
24
- super "Unsupported frame type '#{type}'"
21
+ # Should never be raised as we support all official frame types
22
+ class UnsupportedFrameType < Error
23
+ def initialize(type)
24
+ super "Unsupported frame type '#{type}'"
25
+ end
25
26
  end
26
- end
27
27
 
28
- # Raised if a frame is received but not implemented
29
- class UnsupportedMethodFrame < Error
30
- def initialize(class_id, method_id)
31
- super "Unsupported class/method: #{class_id} #{method_id}"
28
+ # Raised if a frame is received but not implemented
29
+ class UnsupportedMethodFrame < Error
30
+ def initialize(class_id, method_id)
31
+ super "Unsupported class/method: #{class_id} #{method_id}"
32
+ end
32
33
  end
33
- end
34
34
 
35
- # Raised if channel is already closed
36
- class ChannelClosedError < Error
37
- def initialize(id, code, reason, classid = 0, methodid = 0)
38
- super "Channel[#{id}] closed (#{code}) #{reason} (#{classid}/#{methodid})"
35
+ # Raised if channel is already closed
36
+ class ChannelClosed < Error
37
+ def initialize(id, code, reason, classid = 0, methodid = 0)
38
+ super "Channel[#{id}] closed (#{code}) #{reason} (#{classid}/#{methodid})"
39
+ end
39
40
  end
41
+
42
+ # Raised if connection is unexpectedly closed
43
+ class ConnectionClosed < Error; end
40
44
  end
41
45
  end
42
46
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AMQP
4
+ class Client
5
+ # High level representation of an exchange
6
+ class Exchange
7
+ # Should only be initialized from the Client
8
+ # @api private
9
+ def initialize(client, name)
10
+ @client = client
11
+ @name = name
12
+ end
13
+
14
+ # Publish to the exchange
15
+ # @param body [String] The message body
16
+ # @param routing_key [String] The routing key of the message,
17
+ # the exchange may use this when routing the message to bound queues
18
+ # @param properties [Properties]
19
+ # @option properties [String] content_type Content type of the message body
20
+ # @option properties [String] content_encoding Content encoding of the body
21
+ # @option properties [Hash<String, Object>] headers Custom headers
22
+ # @option properties [Integer] delivery_mode 2 for persisted message, transient messages for all other values
23
+ # @option properties [Integer] priority A priority of the message (between 0 and 255)
24
+ # @option properties [Integer] correlation_id A correlation id, most often used used for RPC communication
25
+ # @option properties [String] reply_to Queue to reply RPC responses to
26
+ # @option properties [Integer, String] expiration Number of seconds the message will stay in the queue
27
+ # @option properties [String] message_id Can be used to uniquely identify the message, e.g. for deduplication
28
+ # @option properties [Date] timestamp Often used for the time the message was originally generated
29
+ # @option properties [String] type Can indicate what kind of message this is
30
+ # @option properties [String] user_id Can be used to verify that this is the user that published the message
31
+ # @option properties [String] app_id Can be used to indicates which app that generated the message
32
+ # @return [Exchange] self
33
+ def publish(body, routing_key, **properties)
34
+ @client.publish(body, @name, routing_key, **properties)
35
+ self
36
+ end
37
+
38
+ # Bind to another exchange
39
+ # @param exchange [String] Name of the exchange to bind to
40
+ # @param binding_key [String] Binding key on which messages that match might be routed (depending on exchange type)
41
+ # @param arguments [Hash] Message headers to match on (only relevant for header exchanges)
42
+ # @return [Exchange] self
43
+ def bind(exchange, binding_key, arguments: {})
44
+ @client.exchange_bind(@name, exchange, binding_key, arguments: arguments)
45
+ self
46
+ end
47
+
48
+ # Unbind from another exchange
49
+ # @param exchange [String] Name of the exchange to unbind from
50
+ # @param binding_key [String] Binding key which the queue is bound to the exchange with
51
+ # @param arguments [Hash] Arguments matching the binding that's being removed
52
+ # @return [Exchange] self
53
+ def unbind(exchange, binding_key, arguments: {})
54
+ @client.exchange_unbind(@name, exchange, binding_key, arguments: arguments)
55
+ self
56
+ end
57
+
58
+ # Delete the exchange
59
+ # @return [nil]
60
+ def delete
61
+ @client.delete_exchange(@name)
62
+ nil
63
+ end
64
+ end
65
+ end
66
+ end
@@ -4,528 +4,532 @@ require_relative "./properties"
4
4
  require_relative "./table"
5
5
 
6
6
  module AMQP
7
- # Generate binary data for different frames
8
- # Each frame type implemented as a method
9
- # Having a class for each frame type is more expensive in terms of CPU and memory
10
- module FrameBytes
11
- module_function
12
-
13
- def connection_start_ok(response, properties)
14
- prop_tbl = Table.encode(properties)
15
- [
16
- 1, # type: method
17
- 0, # channel id
18
- 2 + 2 + 4 + prop_tbl.bytesize + 6 + 4 + response.bytesize + 1, # frame size
19
- 10, # class id
20
- 11, # method id
21
- prop_tbl.bytesize, prop_tbl, # client props
22
- 5, "PLAIN", # mechanism
23
- response.bytesize, response,
24
- 0, "", # locale
25
- 206 # frame end
26
- ].pack("C S> L> S> S> L>a* Ca* L>a* Ca* C")
27
- end
28
-
29
- def connection_tune_ok(channel_max, frame_max, heartbeat)
30
- [
31
- 1, # type: method
32
- 0, # channel id
33
- 12, # frame size
34
- 10, # class: connection
35
- 31, # method: tune-ok
36
- channel_max,
37
- frame_max,
38
- heartbeat,
39
- 206 # frame end
40
- ].pack("CS>L>S>S>S>L>S>C")
41
- end
42
-
43
- def connection_open(vhost)
44
- [
45
- 1, # type: method
46
- 0, # channel id
47
- 2 + 2 + 1 + vhost.bytesize + 1 + 1, # frame_size
48
- 10, # class: connection
49
- 40, # method: open
50
- vhost.bytesize, vhost,
51
- 0, # reserved1
52
- 0, # reserved2
53
- 206 # frame end
54
- ].pack("C S> L> S> S> Ca* CCC")
55
- end
56
-
57
- def connection_close(code, reason)
58
- frame_size = 2 + 2 + 2 + 1 + reason.bytesize + 2 + 2
59
- [
60
- 1, # type: method
61
- 0, # channel id
62
- frame_size, # frame size
63
- 10, # class: connection
64
- 50, # method: close
65
- code,
66
- reason.bytesize, reason,
67
- 0, # error class id
68
- 0, # error method id
69
- 206 # frame end
70
- ].pack("C S> L> S> S> S> Ca* S> S> C")
71
- end
72
-
73
- def connection_close_ok
74
- [
75
- 1, # type: method
76
- 0, # channel id
77
- 4, # frame size
78
- 10, # class: connection
79
- 51, # method: close-ok
80
- 206 # frame end
81
- ].pack("C S> L> S> S> C")
82
- end
83
-
84
- def channel_open(id)
85
- [
86
- 1, # type: method
87
- id, # channel id
88
- 5, # frame size
89
- 20, # class: channel
90
- 10, # method: open
91
- 0, # reserved1
92
- 206 # frame end
93
- ].pack("C S> L> S> S> C C")
94
- end
95
-
96
- def channel_close(id, reason, code)
97
- frame_size = 2 + 2 + 2 + 1 + reason.bytesize + 2 + 2
98
- [
99
- 1, # type: method
100
- id, # channel id
101
- frame_size, # frame size
102
- 20, # class: channel
103
- 40, # method: close
104
- code,
105
- reason.bytesize, reason,
106
- 0, # error class id
107
- 0, # error method id
108
- 206 # frame end
109
- ].pack("C S> L> S> S> S> Ca* S> S> C")
110
- end
111
-
112
- def channel_close_ok(id)
113
- [
114
- 1, # type: method
115
- id, # channel id
116
- 4, # frame size
117
- 20, # class: channel
118
- 41, # method: close-ok
119
- 206 # frame end
120
- ].pack("C S> L> S> S> C")
121
- end
122
-
123
- def exchange_declare(id, name, type, passive, durable, auto_delete, internal, arguments)
124
- no_wait = false
125
- bits = 0
126
- bits |= (1 << 0) if passive
127
- bits |= (1 << 1) if durable
128
- bits |= (1 << 2) if auto_delete
129
- bits |= (1 << 3) if internal
130
- bits |= (1 << 4) if no_wait
131
- tbl = Table.encode(arguments)
132
- frame_size = 2 + 2 + 2 + 1 + name.bytesize + 1 + type.bytesize + 1 + 4 + tbl.bytesize
133
- [
134
- 1, # type: method
135
- id, # channel id
136
- frame_size, # frame size
137
- 40, # class: exchange
138
- 10, # method: declare
139
- 0, # reserved1
140
- name.bytesize, name,
141
- type.bytesize, type,
142
- bits,
143
- tbl.bytesize, tbl, # arguments
144
- 206 # frame end
145
- ].pack("C S> L> S> S> S> Ca* Ca* C L>a* C")
146
- end
147
-
148
- def exchange_delete(id, name, if_unused, no_wait)
149
- bits = 0
150
- bits |= (1 << 0) if if_unused
151
- bits |= (1 << 1) if no_wait
152
- frame_size = 2 + 2 + 2 + 1 + name.bytesize + 1
153
- [
154
- 1, # type: method
155
- id, # channel id
156
- frame_size, # frame size
157
- 40, # class: exchange
158
- 20, # method: delete
159
- 0, # reserved1
160
- name.bytesize, name,
161
- bits,
162
- 206 # frame end
163
- ].pack("C S> L> S> S> S> Ca* C C")
164
- end
165
-
166
- def exchange_bind(id, destination, source, binding_key, no_wait, arguments)
167
- tbl = Table.encode(arguments)
168
- frame_size = 2 + 2 + 2 + 1 + destination.bytesize + 1 + source.bytesize + 1 +
169
- binding_key.bytesize + 1 + 4 + tbl.bytesize
170
- [
171
- 1, # type: method
172
- id, # channel id
173
- frame_size, # frame size
174
- 40, # class: exchange
175
- 30, # method: bind
176
- 0, # reserved1
177
- destination.bytesize, destination,
178
- source.bytesize, source,
179
- binding_key.bytesize, binding_key,
180
- no_wait ? 1 : 0,
181
- tbl.bytesize, tbl, # arguments
182
- 206 # frame end
183
- ].pack("C S> L> S> S> S> Ca* Ca* Ca* C L>a* C")
184
- end
185
-
186
- def exchange_unbind(id, destination, source, binding_key, no_wait, arguments)
187
- tbl = Table.encode(arguments)
188
- frame_size = 2 + 2 + 2 + 1 + destination.bytesize + 1 + source.bytesize + 1 +
189
- binding_key.bytesize + 1 + 4 + tbl.bytesize
190
- [
191
- 1, # type: method
192
- id, # channel id
193
- frame_size, # frame size
194
- 40, # class: exchange
195
- 40, # method: unbind
196
- 0, # reserved1
197
- destination.bytesize, destination,
198
- source.bytesize, source,
199
- binding_key.bytesize, binding_key,
200
- no_wait ? 1 : 0,
201
- tbl.bytesize, tbl, # arguments
202
- 206 # frame end
203
- ].pack("C S> L> S> S> S> Ca* Ca* Ca* C L>a* C")
204
- end
205
-
206
- def queue_declare(id, name, passive, durable, exclusive, auto_delete, arguments)
207
- no_wait = false
208
- bits = 0
209
- bits |= (1 << 0) if passive
210
- bits |= (1 << 1) if durable
211
- bits |= (1 << 2) if exclusive
212
- bits |= (1 << 3) if auto_delete
213
- bits |= (1 << 4) if no_wait
214
- tbl = Table.encode(arguments)
215
- frame_size = 2 + 2 + 2 + 1 + name.bytesize + 1 + 4 + tbl.bytesize
216
- [
217
- 1, # type: method
218
- id, # channel id
219
- frame_size, # frame size
220
- 50, # class: queue
221
- 10, # method: declare
222
- 0, # reserved1
223
- name.bytesize, name,
224
- bits,
225
- tbl.bytesize, tbl, # arguments
226
- 206 # frame end
227
- ].pack("C S> L> S> S> S> Ca* C L>a* C")
228
- end
229
-
230
- def queue_delete(id, name, if_unused, if_empty, no_wait)
231
- bits = 0
232
- bits |= (1 << 0) if if_unused
233
- bits |= (1 << 1) if if_empty
234
- bits |= (1 << 2) if no_wait
235
- frame_size = 2 + 2 + 2 + 1 + name.bytesize + 1
236
- [
237
- 1, # type: method
238
- id, # channel id
239
- frame_size, # frame size
240
- 50, # class: queue
241
- 40, # method: declare
242
- 0, # reserved1
243
- name.bytesize, name,
244
- bits,
245
- 206 # frame end
246
- ].pack("C S> L> S> S> S> Ca* C C")
247
- end
248
-
249
- def queue_bind(id, queue, exchange, binding_key, no_wait, arguments)
250
- tbl = Table.encode(arguments)
251
- frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1 + exchange.bytesize + 1 +
252
- binding_key.bytesize + 1 + 4 + tbl.bytesize
253
- [
254
- 1, # type: method
255
- id, # channel id
256
- frame_size, # frame size
257
- 50, # class: queue
258
- 20, # method: bind
259
- 0, # reserved1
260
- queue.bytesize, queue,
261
- exchange.bytesize, exchange,
262
- binding_key.bytesize, binding_key,
263
- no_wait ? 1 : 0,
264
- tbl.bytesize, tbl, # arguments
265
- 206 # frame end
266
- ].pack("C S> L> S> S> S> Ca* Ca* Ca* C L>a* C")
267
- end
268
-
269
- def queue_unbind(id, queue, exchange, binding_key, arguments)
270
- tbl = Table.encode(arguments)
271
- frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1 + exchange.bytesize + 1 + binding_key.bytesize + 4 + tbl.bytesize
272
- [
273
- 1, # type: method
274
- id, # channel id
275
- frame_size, # frame size
276
- 50, # class: queue
277
- 50, # method: unbind
278
- 0, # reserved1
279
- queue.bytesize, queue,
280
- exchange.bytesize, exchange,
281
- binding_key.bytesize, binding_key,
282
- tbl.bytesize, tbl, # arguments
283
- 206 # frame end
284
- ].pack("C S> L> S> S> S> Ca* Ca* Ca* L>a* C")
285
- end
286
-
287
- def queue_purge(id, queue, no_wait)
288
- frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1
289
- [
290
- 1, # type: method
291
- id, # channel id
292
- frame_size, # frame size
293
- 50, # class: queue
294
- 30, # method: purge
295
- 0, # reserved1
296
- queue.bytesize, queue,
297
- no_wait ? 1 : 0,
298
- 206 # frame end
299
- ].pack("C S> L> S> S> S> Ca* C C")
300
- end
301
-
302
- def basic_get(id, queue, no_ack)
303
- frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1
304
- [
305
- 1, # type: method
306
- id, # channel id
307
- frame_size, # frame size
308
- 60, # class: basic
309
- 70, # method: get
310
- 0, # reserved1
311
- queue.bytesize, queue,
312
- no_ack ? 1 : 0,
313
- 206 # frame end
314
- ].pack("C S> L> S> S> S> Ca* C C")
315
- end
316
-
317
- def basic_publish(id, exchange, routing_key, mandatory)
318
- frame_size = 2 + 2 + 2 + 1 + exchange.bytesize + 1 + routing_key.bytesize + 1
319
- [
320
- 1, # type: method
321
- id, # channel id
322
- frame_size, # frame size
323
- 60, # class: basic
324
- 40, # method: publish
325
- 0, # reserved1
326
- exchange.bytesize, exchange,
327
- routing_key.bytesize, routing_key,
328
- mandatory ? 1 : 0, # bits, mandatory/immediate
329
- 206 # frame end
330
- ].pack("C S> L> S> S> S> Ca* Ca* C C")
331
- end
332
-
333
- def header(id, body_size, properties)
334
- props = Properties.new(**properties).encode
335
- frame_size = 2 + 2 + 8 + props.bytesize
336
- [
337
- 2, # type: header
338
- id, # channel id
339
- frame_size, # frame size
340
- 60, # class: basic
341
- 0, # weight
342
- body_size,
343
- props, # properties
344
- 206 # frame end
345
- ].pack("C S> L> S> S> Q> a* C")
346
- end
347
-
348
- def body(id, body_part)
349
- [
350
- 3, # type: body
351
- id, # channel id
352
- body_part.bytesize, # frame size
353
- body_part,
354
- 206 # frame end
355
- ].pack("C S> L> a* C")
356
- end
357
-
358
- def basic_consume(id, queue, tag, no_ack, exclusive, arguments)
359
- no_local = false
360
- no_wait = false
361
- bits = 0
362
- bits |= (1 << 0) if no_local
363
- bits |= (1 << 1) if no_ack
364
- bits |= (1 << 2) if exclusive
365
- bits |= (1 << 3) if no_wait
366
- tbl = Table.encode(arguments)
367
- frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1 + tag.bytesize + 1 + 4 + tbl.bytesize
368
- [
369
- 1, # type: method
370
- id, # channel id
371
- frame_size, # frame size
372
- 60, # class: basic
373
- 20, # method: consume
374
- 0, # reserved1
375
- queue.bytesize, queue,
376
- tag.bytesize, tag,
377
- bits, # bits
378
- tbl.bytesize, tbl, # arguments
379
- 206 # frame end
380
- ].pack("C S> L> S> S> S> Ca* Ca* C L>a* C")
381
- end
382
-
383
- def basic_cancel(id, consumer_tag, no_wait: false)
384
- frame_size = 2 + 2 + 1 + consumer_tag.bytesize + 1
385
- [
386
- 1, # type: method
387
- id, # channel id
388
- frame_size, # frame size
389
- 60, # class: basic
390
- 30, # method: cancel
391
- consumer_tag.bytesize, consumer_tag,
392
- no_wait ? 1 : 0,
393
- 206 # frame end
394
- ].pack("C S> L> S> S> Ca* C C")
395
- end
396
-
397
- def basic_cancel_ok(id, consumer_tag)
398
- frame_size = 2 + 2 + 1 + consumer_tag.bytesize + 1
399
- [
400
- 1, # type: method
401
- id, # channel id
402
- frame_size, # frame size
403
- 60, # class: basic
404
- 31, # method: cancel-ok
405
- consumer_tag.bytesize, consumer_tag,
406
- 206 # frame end
407
- ].pack("C S> L> S> S> Ca* C")
408
- end
409
-
410
- def basic_ack(id, delivery_tag, multiple)
411
- frame_size = 2 + 2 + 8 + 1
412
- [
413
- 1, # type: method
414
- id, # channel id
415
- frame_size, # frame size
416
- 60, # class: basic
417
- 80, # method: ack
418
- delivery_tag,
419
- multiple ? 1 : 0,
420
- 206 # frame end
421
- ].pack("C S> L> S> S> Q> C C")
422
- end
423
-
424
- def basic_nack(id, delivery_tag, multiple, requeue)
425
- bits = 0
426
- bits |= (1 << 0) if multiple
427
- bits |= (1 << 1) if requeue
428
- frame_size = 2 + 2 + 8 + 1
429
- [
430
- 1, # type: method
431
- id, # channel id
432
- frame_size, # frame size
433
- 60, # class: basic
434
- 120, # method: nack
435
- delivery_tag,
436
- bits,
437
- 206 # frame end
438
- ].pack("C S> L> S> S> Q> C C")
439
- end
440
-
441
- def basic_reject(id, delivery_tag, requeue)
442
- frame_size = 2 + 2 + 8 + 1
443
- [
444
- 1, # type: method
445
- id, # channel id
446
- frame_size, # frame size
447
- 60, # class: basic
448
- 90, # method: reject
449
- delivery_tag,
450
- requeue ? 1 : 0,
451
- 206 # frame end
452
- ].pack("C S> L> S> S> Q> C C")
453
- end
454
-
455
- def basic_qos(id, prefetch_size, prefetch_count, global)
456
- frame_size = 2 + 2 + 4 + 2 + 1
457
- [
458
- 1, # type: method
459
- id, # channel id
460
- frame_size, # frame size
461
- 60, # class: basic
462
- 10, # method: qos
463
- prefetch_size,
464
- prefetch_count,
465
- global ? 1 : 0,
466
- 206 # frame end
467
- ].pack("C S> L> S> S> L> S> C C")
468
- end
469
-
470
- def basic_recover(id, requeue)
471
- frame_size = 2 + 2 + 1
472
- [
473
- 1, # type: method
474
- id, # channel id
475
- frame_size, # frame size
476
- 60, # class: basic
477
- 110, # method: recover
478
- requeue ? 1 : 0,
479
- 206 # frame end
480
- ].pack("C S> L> S> S> C C")
481
- end
482
-
483
- def confirm_select(id, no_wait)
484
- [
485
- 1, # type: method
486
- id, # channel id
487
- 5, # frame size
488
- 85, # class: confirm
489
- 10, # method: select
490
- no_wait ? 1 : 0,
491
- 206 # frame end
492
- ].pack("C S> L> S> S> C C")
493
- end
494
-
495
- def tx_select(id)
496
- frame_size = 2 + 2
497
- [
498
- 1, # type: method
499
- id, # channel id
500
- frame_size, # frame size
501
- 90, # class: tx
502
- 10, # method: select
503
- 206 # frame end
504
- ].pack("C S> L> S> S> C")
505
- end
506
-
507
- def tx_commit(id)
508
- frame_size = 2 + 2
509
- [
510
- 1, # type: method
511
- id, # channel id
512
- frame_size, # frame size
513
- 90, # class: tx
514
- 20, # method: commit
515
- 206 # frame end
516
- ].pack("C S> L> S> S> C")
517
- end
518
-
519
- def tx_rollback(id)
520
- frame_size = 2 + 2
521
- [
522
- 1, # type: method
523
- id, # channel id
524
- frame_size, # frame size
525
- 90, # class: tx
526
- 30, # method: rollback
527
- 206 # frame end
528
- ].pack("C S> L> S> S> C")
7
+ class Client
8
+ # Generate binary data for different frames
9
+ # Each frame type implemented as a method
10
+ # Having a class for each frame type is more expensive in terms of CPU and memory
11
+ # @api private
12
+ module FrameBytes
13
+ module_function
14
+
15
+ def connection_start_ok(response, properties)
16
+ prop_tbl = Table.encode(properties)
17
+ [
18
+ 1, # type: method
19
+ 0, # channel id
20
+ 2 + 2 + 4 + prop_tbl.bytesize + 6 + 4 + response.bytesize + 1, # frame size
21
+ 10, # class id
22
+ 11, # method id
23
+ prop_tbl.bytesize, prop_tbl, # client props
24
+ 5, "PLAIN", # mechanism
25
+ response.bytesize, response,
26
+ 0, "", # locale
27
+ 206 # frame end
28
+ ].pack("C S> L> S> S> L>a* Ca* L>a* Ca* C")
29
+ end
30
+
31
+ def connection_tune_ok(channel_max, frame_max, heartbeat)
32
+ [
33
+ 1, # type: method
34
+ 0, # channel id
35
+ 12, # frame size
36
+ 10, # class: connection
37
+ 31, # method: tune-ok
38
+ channel_max,
39
+ frame_max,
40
+ heartbeat,
41
+ 206 # frame end
42
+ ].pack("CS>L>S>S>S>L>S>C")
43
+ end
44
+
45
+ def connection_open(vhost)
46
+ [
47
+ 1, # type: method
48
+ 0, # channel id
49
+ 2 + 2 + 1 + vhost.bytesize + 1 + 1, # frame_size
50
+ 10, # class: connection
51
+ 40, # method: open
52
+ vhost.bytesize, vhost,
53
+ 0, # reserved1
54
+ 0, # reserved2
55
+ 206 # frame end
56
+ ].pack("C S> L> S> S> Ca* CCC")
57
+ end
58
+
59
+ def connection_close(code, reason)
60
+ frame_size = 2 + 2 + 2 + 1 + reason.bytesize + 2 + 2
61
+ [
62
+ 1, # type: method
63
+ 0, # channel id
64
+ frame_size, # frame size
65
+ 10, # class: connection
66
+ 50, # method: close
67
+ code,
68
+ reason.bytesize, reason,
69
+ 0, # error class id
70
+ 0, # error method id
71
+ 206 # frame end
72
+ ].pack("C S> L> S> S> S> Ca* S> S> C")
73
+ end
74
+
75
+ def connection_close_ok
76
+ [
77
+ 1, # type: method
78
+ 0, # channel id
79
+ 4, # frame size
80
+ 10, # class: connection
81
+ 51, # method: close-ok
82
+ 206 # frame end
83
+ ].pack("C S> L> S> S> C")
84
+ end
85
+
86
+ def channel_open(id)
87
+ [
88
+ 1, # type: method
89
+ id, # channel id
90
+ 5, # frame size
91
+ 20, # class: channel
92
+ 10, # method: open
93
+ 0, # reserved1
94
+ 206 # frame end
95
+ ].pack("C S> L> S> S> C C")
96
+ end
97
+
98
+ def channel_close(id, reason, code)
99
+ frame_size = 2 + 2 + 2 + 1 + reason.bytesize + 2 + 2
100
+ [
101
+ 1, # type: method
102
+ id, # channel id
103
+ frame_size, # frame size
104
+ 20, # class: channel
105
+ 40, # method: close
106
+ code,
107
+ reason.bytesize, reason,
108
+ 0, # error class id
109
+ 0, # error method id
110
+ 206 # frame end
111
+ ].pack("C S> L> S> S> S> Ca* S> S> C")
112
+ end
113
+
114
+ def channel_close_ok(id)
115
+ [
116
+ 1, # type: method
117
+ id, # channel id
118
+ 4, # frame size
119
+ 20, # class: channel
120
+ 41, # method: close-ok
121
+ 206 # frame end
122
+ ].pack("C S> L> S> S> C")
123
+ end
124
+
125
+ def exchange_declare(id, name, type, passive, durable, auto_delete, internal, arguments)
126
+ no_wait = false
127
+ bits = 0
128
+ bits |= (1 << 0) if passive
129
+ bits |= (1 << 1) if durable
130
+ bits |= (1 << 2) if auto_delete
131
+ bits |= (1 << 3) if internal
132
+ bits |= (1 << 4) if no_wait
133
+ tbl = Table.encode(arguments)
134
+ frame_size = 2 + 2 + 2 + 1 + name.bytesize + 1 + type.bytesize + 1 + 4 + tbl.bytesize
135
+ [
136
+ 1, # type: method
137
+ id, # channel id
138
+ frame_size, # frame size
139
+ 40, # class: exchange
140
+ 10, # method: declare
141
+ 0, # reserved1
142
+ name.bytesize, name,
143
+ type.bytesize, type,
144
+ bits,
145
+ tbl.bytesize, tbl, # arguments
146
+ 206 # frame end
147
+ ].pack("C S> L> S> S> S> Ca* Ca* C L>a* C")
148
+ end
149
+
150
+ def exchange_delete(id, name, if_unused, no_wait)
151
+ bits = 0
152
+ bits |= (1 << 0) if if_unused
153
+ bits |= (1 << 1) if no_wait
154
+ frame_size = 2 + 2 + 2 + 1 + name.bytesize + 1
155
+ [
156
+ 1, # type: method
157
+ id, # channel id
158
+ frame_size, # frame size
159
+ 40, # class: exchange
160
+ 20, # method: delete
161
+ 0, # reserved1
162
+ name.bytesize, name,
163
+ bits,
164
+ 206 # frame end
165
+ ].pack("C S> L> S> S> S> Ca* C C")
166
+ end
167
+
168
+ def exchange_bind(id, destination, source, binding_key, no_wait, arguments)
169
+ tbl = Table.encode(arguments)
170
+ frame_size = 2 + 2 + 2 + 1 + destination.bytesize + 1 + source.bytesize + 1 +
171
+ binding_key.bytesize + 1 + 4 + tbl.bytesize
172
+ [
173
+ 1, # type: method
174
+ id, # channel id
175
+ frame_size, # frame size
176
+ 40, # class: exchange
177
+ 30, # method: bind
178
+ 0, # reserved1
179
+ destination.bytesize, destination,
180
+ source.bytesize, source,
181
+ binding_key.bytesize, binding_key,
182
+ no_wait ? 1 : 0,
183
+ tbl.bytesize, tbl, # arguments
184
+ 206 # frame end
185
+ ].pack("C S> L> S> S> S> Ca* Ca* Ca* C L>a* C")
186
+ end
187
+
188
+ def exchange_unbind(id, destination, source, binding_key, no_wait, arguments)
189
+ tbl = Table.encode(arguments)
190
+ frame_size = 2 + 2 + 2 + 1 + destination.bytesize + 1 + source.bytesize + 1 +
191
+ binding_key.bytesize + 1 + 4 + tbl.bytesize
192
+ [
193
+ 1, # type: method
194
+ id, # channel id
195
+ frame_size, # frame size
196
+ 40, # class: exchange
197
+ 40, # method: unbind
198
+ 0, # reserved1
199
+ destination.bytesize, destination,
200
+ source.bytesize, source,
201
+ binding_key.bytesize, binding_key,
202
+ no_wait ? 1 : 0,
203
+ tbl.bytesize, tbl, # arguments
204
+ 206 # frame end
205
+ ].pack("C S> L> S> S> S> Ca* Ca* Ca* C L>a* C")
206
+ end
207
+
208
+ def queue_declare(id, name, passive, durable, exclusive, auto_delete, arguments)
209
+ no_wait = false
210
+ bits = 0
211
+ bits |= (1 << 0) if passive
212
+ bits |= (1 << 1) if durable
213
+ bits |= (1 << 2) if exclusive
214
+ bits |= (1 << 3) if auto_delete
215
+ bits |= (1 << 4) if no_wait
216
+ tbl = Table.encode(arguments)
217
+ frame_size = 2 + 2 + 2 + 1 + name.bytesize + 1 + 4 + tbl.bytesize
218
+ [
219
+ 1, # type: method
220
+ id, # channel id
221
+ frame_size, # frame size
222
+ 50, # class: queue
223
+ 10, # method: declare
224
+ 0, # reserved1
225
+ name.bytesize, name,
226
+ bits,
227
+ tbl.bytesize, tbl, # arguments
228
+ 206 # frame end
229
+ ].pack("C S> L> S> S> S> Ca* C L>a* C")
230
+ end
231
+
232
+ def queue_delete(id, name, if_unused, if_empty, no_wait)
233
+ bits = 0
234
+ bits |= (1 << 0) if if_unused
235
+ bits |= (1 << 1) if if_empty
236
+ bits |= (1 << 2) if no_wait
237
+ frame_size = 2 + 2 + 2 + 1 + name.bytesize + 1
238
+ [
239
+ 1, # type: method
240
+ id, # channel id
241
+ frame_size, # frame size
242
+ 50, # class: queue
243
+ 40, # method: declare
244
+ 0, # reserved1
245
+ name.bytesize, name,
246
+ bits,
247
+ 206 # frame end
248
+ ].pack("C S> L> S> S> S> Ca* C C")
249
+ end
250
+
251
+ def queue_bind(id, queue, exchange, binding_key, no_wait, arguments)
252
+ tbl = Table.encode(arguments)
253
+ frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1 + exchange.bytesize + 1 +
254
+ binding_key.bytesize + 1 + 4 + tbl.bytesize
255
+ [
256
+ 1, # type: method
257
+ id, # channel id
258
+ frame_size, # frame size
259
+ 50, # class: queue
260
+ 20, # method: bind
261
+ 0, # reserved1
262
+ queue.bytesize, queue,
263
+ exchange.bytesize, exchange,
264
+ binding_key.bytesize, binding_key,
265
+ no_wait ? 1 : 0,
266
+ tbl.bytesize, tbl, # arguments
267
+ 206 # frame end
268
+ ].pack("C S> L> S> S> S> Ca* Ca* Ca* C L>a* C")
269
+ end
270
+
271
+ def queue_unbind(id, queue, exchange, binding_key, arguments)
272
+ tbl = Table.encode(arguments)
273
+ frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1 + exchange.bytesize + 1 +
274
+ binding_key.bytesize + 4 + tbl.bytesize
275
+ [
276
+ 1, # type: method
277
+ id, # channel id
278
+ frame_size, # frame size
279
+ 50, # class: queue
280
+ 50, # method: unbind
281
+ 0, # reserved1
282
+ queue.bytesize, queue,
283
+ exchange.bytesize, exchange,
284
+ binding_key.bytesize, binding_key,
285
+ tbl.bytesize, tbl, # arguments
286
+ 206 # frame end
287
+ ].pack("C S> L> S> S> S> Ca* Ca* Ca* L>a* C")
288
+ end
289
+
290
+ def queue_purge(id, queue, no_wait)
291
+ frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1
292
+ [
293
+ 1, # type: method
294
+ id, # channel id
295
+ frame_size, # frame size
296
+ 50, # class: queue
297
+ 30, # method: purge
298
+ 0, # reserved1
299
+ queue.bytesize, queue,
300
+ no_wait ? 1 : 0,
301
+ 206 # frame end
302
+ ].pack("C S> L> S> S> S> Ca* C C")
303
+ end
304
+
305
+ def basic_get(id, queue, no_ack)
306
+ frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1
307
+ [
308
+ 1, # type: method
309
+ id, # channel id
310
+ frame_size, # frame size
311
+ 60, # class: basic
312
+ 70, # method: get
313
+ 0, # reserved1
314
+ queue.bytesize, queue,
315
+ no_ack ? 1 : 0,
316
+ 206 # frame end
317
+ ].pack("C S> L> S> S> S> Ca* C C")
318
+ end
319
+
320
+ def basic_publish(id, exchange, routing_key, mandatory)
321
+ frame_size = 2 + 2 + 2 + 1 + exchange.bytesize + 1 + routing_key.bytesize + 1
322
+ [
323
+ 1, # type: method
324
+ id, # channel id
325
+ frame_size, # frame size
326
+ 60, # class: basic
327
+ 40, # method: publish
328
+ 0, # reserved1
329
+ exchange.bytesize, exchange,
330
+ routing_key.bytesize, routing_key,
331
+ mandatory ? 1 : 0, # bits, mandatory/immediate
332
+ 206 # frame end
333
+ ].pack("C S> L> S> S> S> Ca* Ca* C C")
334
+ end
335
+
336
+ def header(id, body_size, properties)
337
+ props = Properties.new(**properties).encode
338
+ frame_size = 2 + 2 + 8 + props.bytesize
339
+ [
340
+ 2, # type: header
341
+ id, # channel id
342
+ frame_size, # frame size
343
+ 60, # class: basic
344
+ 0, # weight
345
+ body_size,
346
+ props, # properties
347
+ 206 # frame end
348
+ ].pack("C S> L> S> S> Q> a* C")
349
+ end
350
+
351
+ def body(id, body_part)
352
+ [
353
+ 3, # type: body
354
+ id, # channel id
355
+ body_part.bytesize, # frame size
356
+ body_part,
357
+ 206 # frame end
358
+ ].pack("C S> L> a* C")
359
+ end
360
+
361
+ def basic_consume(id, queue, tag, no_ack, exclusive, arguments)
362
+ no_local = false
363
+ no_wait = false
364
+ bits = 0
365
+ bits |= (1 << 0) if no_local
366
+ bits |= (1 << 1) if no_ack
367
+ bits |= (1 << 2) if exclusive
368
+ bits |= (1 << 3) if no_wait
369
+ tbl = Table.encode(arguments)
370
+ frame_size = 2 + 2 + 2 + 1 + queue.bytesize + 1 + tag.bytesize + 1 + 4 + tbl.bytesize
371
+ [
372
+ 1, # type: method
373
+ id, # channel id
374
+ frame_size, # frame size
375
+ 60, # class: basic
376
+ 20, # method: consume
377
+ 0, # reserved1
378
+ queue.bytesize, queue,
379
+ tag.bytesize, tag,
380
+ bits, # bits
381
+ tbl.bytesize, tbl, # arguments
382
+ 206 # frame end
383
+ ].pack("C S> L> S> S> S> Ca* Ca* C L>a* C")
384
+ end
385
+
386
+ def basic_cancel(id, consumer_tag, no_wait: false)
387
+ frame_size = 2 + 2 + 1 + consumer_tag.bytesize + 1
388
+ [
389
+ 1, # type: method
390
+ id, # channel id
391
+ frame_size, # frame size
392
+ 60, # class: basic
393
+ 30, # method: cancel
394
+ consumer_tag.bytesize, consumer_tag,
395
+ no_wait ? 1 : 0,
396
+ 206 # frame end
397
+ ].pack("C S> L> S> S> Ca* C C")
398
+ end
399
+
400
+ def basic_cancel_ok(id, consumer_tag)
401
+ frame_size = 2 + 2 + 1 + consumer_tag.bytesize + 1
402
+ [
403
+ 1, # type: method
404
+ id, # channel id
405
+ frame_size, # frame size
406
+ 60, # class: basic
407
+ 31, # method: cancel-ok
408
+ consumer_tag.bytesize, consumer_tag,
409
+ 206 # frame end
410
+ ].pack("C S> L> S> S> Ca* C")
411
+ end
412
+
413
+ def basic_ack(id, delivery_tag, multiple)
414
+ frame_size = 2 + 2 + 8 + 1
415
+ [
416
+ 1, # type: method
417
+ id, # channel id
418
+ frame_size, # frame size
419
+ 60, # class: basic
420
+ 80, # method: ack
421
+ delivery_tag,
422
+ multiple ? 1 : 0,
423
+ 206 # frame end
424
+ ].pack("C S> L> S> S> Q> C C")
425
+ end
426
+
427
+ def basic_nack(id, delivery_tag, multiple, requeue)
428
+ bits = 0
429
+ bits |= (1 << 0) if multiple
430
+ bits |= (1 << 1) if requeue
431
+ frame_size = 2 + 2 + 8 + 1
432
+ [
433
+ 1, # type: method
434
+ id, # channel id
435
+ frame_size, # frame size
436
+ 60, # class: basic
437
+ 120, # method: nack
438
+ delivery_tag,
439
+ bits,
440
+ 206 # frame end
441
+ ].pack("C S> L> S> S> Q> C C")
442
+ end
443
+
444
+ def basic_reject(id, delivery_tag, requeue)
445
+ frame_size = 2 + 2 + 8 + 1
446
+ [
447
+ 1, # type: method
448
+ id, # channel id
449
+ frame_size, # frame size
450
+ 60, # class: basic
451
+ 90, # method: reject
452
+ delivery_tag,
453
+ requeue ? 1 : 0,
454
+ 206 # frame end
455
+ ].pack("C S> L> S> S> Q> C C")
456
+ end
457
+
458
+ def basic_qos(id, prefetch_size, prefetch_count, global)
459
+ frame_size = 2 + 2 + 4 + 2 + 1
460
+ [
461
+ 1, # type: method
462
+ id, # channel id
463
+ frame_size, # frame size
464
+ 60, # class: basic
465
+ 10, # method: qos
466
+ prefetch_size,
467
+ prefetch_count,
468
+ global ? 1 : 0,
469
+ 206 # frame end
470
+ ].pack("C S> L> S> S> L> S> C C")
471
+ end
472
+
473
+ def basic_recover(id, requeue)
474
+ frame_size = 2 + 2 + 1
475
+ [
476
+ 1, # type: method
477
+ id, # channel id
478
+ frame_size, # frame size
479
+ 60, # class: basic
480
+ 110, # method: recover
481
+ requeue ? 1 : 0,
482
+ 206 # frame end
483
+ ].pack("C S> L> S> S> C C")
484
+ end
485
+
486
+ def confirm_select(id, no_wait)
487
+ [
488
+ 1, # type: method
489
+ id, # channel id
490
+ 5, # frame size
491
+ 85, # class: confirm
492
+ 10, # method: select
493
+ no_wait ? 1 : 0,
494
+ 206 # frame end
495
+ ].pack("C S> L> S> S> C C")
496
+ end
497
+
498
+ def tx_select(id)
499
+ frame_size = 2 + 2
500
+ [
501
+ 1, # type: method
502
+ id, # channel id
503
+ frame_size, # frame size
504
+ 90, # class: tx
505
+ 10, # method: select
506
+ 206 # frame end
507
+ ].pack("C S> L> S> S> C")
508
+ end
509
+
510
+ def tx_commit(id)
511
+ frame_size = 2 + 2
512
+ [
513
+ 1, # type: method
514
+ id, # channel id
515
+ frame_size, # frame size
516
+ 90, # class: tx
517
+ 20, # method: commit
518
+ 206 # frame end
519
+ ].pack("C S> L> S> S> C")
520
+ end
521
+
522
+ def tx_rollback(id)
523
+ frame_size = 2 + 2
524
+ [
525
+ 1, # type: method
526
+ id, # channel id
527
+ frame_size, # frame size
528
+ 90, # class: tx
529
+ 30, # method: rollback
530
+ 206 # frame end
531
+ ].pack("C S> L> S> S> C")
532
+ end
529
533
  end
530
534
  end
531
535
  end