amq-client 0.7.0.alpha34 → 0.7.0.alpha35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. data/.travis.yml +4 -0
  2. data/Gemfile +1 -1
  3. data/README.textile +1 -1
  4. data/bin/ci/before_build.sh +24 -0
  5. data/examples/eventmachine_adapter/extensions/rabbitmq/handling_confirm_select_ok.rb +2 -2
  6. data/examples/eventmachine_adapter/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +1 -1
  7. data/examples/eventmachine_adapter/extensions/rabbitmq/publisher_confirmations_with_unroutable_message.rb +1 -1
  8. data/lib/amq/client.rb +29 -17
  9. data/lib/amq/client/adapter.rb +8 -504
  10. data/lib/amq/client/adapters/coolio.rb +4 -282
  11. data/lib/amq/client/adapters/event_machine.rb +4 -382
  12. data/lib/amq/client/async/adapter.rb +517 -0
  13. data/lib/amq/client/async/adapters/coolio.rb +291 -0
  14. data/lib/amq/client/async/adapters/event_machine.rb +392 -0
  15. data/lib/amq/client/async/adapters/eventmachine.rb +1 -0
  16. data/lib/amq/client/async/callbacks.rb +71 -0
  17. data/lib/amq/client/async/channel.rb +385 -0
  18. data/lib/amq/client/async/entity.rb +66 -0
  19. data/lib/amq/client/async/exchange.rb +157 -0
  20. data/lib/amq/client/async/extensions/rabbitmq/basic.rb +38 -0
  21. data/lib/amq/client/async/extensions/rabbitmq/confirm.rb +248 -0
  22. data/lib/amq/client/async/queue.rb +455 -0
  23. data/lib/amq/client/callbacks.rb +6 -65
  24. data/lib/amq/client/channel.rb +4 -376
  25. data/lib/amq/client/entity.rb +6 -57
  26. data/lib/amq/client/exchange.rb +4 -148
  27. data/lib/amq/client/extensions/rabbitmq/basic.rb +4 -28
  28. data/lib/amq/client/extensions/rabbitmq/confirm.rb +5 -240
  29. data/lib/amq/client/queue.rb +5 -450
  30. data/lib/amq/client/version.rb +1 -1
  31. data/spec/unit/client_spec.rb +10 -30
  32. metadata +16 -22
@@ -1,69 +1,10 @@
1
+ require "amq/client/async/callbacks"
2
+
1
3
  module AMQ
2
4
  module Client
3
- module Callbacks
4
-
5
- def redefine_callback(event, callable = nil, &block)
6
- f = (callable || block)
7
- # yes, re-assign!
8
- @callbacks[event] = [f]
9
-
10
- self
11
- end
12
-
13
- def define_callback(event, callable = nil, &block)
14
- f = (callable || block)
15
-
16
- @callbacks[event] ||= []
17
- @callbacks[event] << f if f
18
-
19
- self
20
- end # define_callback(event, &block)
21
- alias append_callback define_callback
22
-
23
- def prepend_callback(event, &block)
24
- @callbacks[event] ||= []
25
- @callbacks[event].unshift(block)
26
-
27
- self
28
- end # prepend_callback(event, &block)
29
-
30
- def clear_callbacks(event)
31
- @callbacks[event].clear if @callbacks[event]
32
- end # clear_callbacks(event)
33
-
34
-
35
- def exec_callback(name, *args, &block)
36
- list = Array(self.callbacks[name])
37
- if list.any?
38
- list.each { |c| c.call(*args, &block) }
39
- end
40
- end
41
-
42
- def exec_callback_once(name, *args, &block)
43
- list = (self.callbacks.delete(name) || Array.new)
44
- if list.any?
45
- list.each { |c| c.call(*args, &block) }
46
- end
47
- end
48
-
49
- def exec_callback_yielding_self(name, *args, &block)
50
- list = Array(self.callbacks[name])
51
- if list.any?
52
- list.each { |c| c.call(self, *args, &block) }
53
- end
54
- end
55
-
56
- def exec_callback_once_yielding_self(name, *args, &block)
57
- list = (self.callbacks.delete(name) || Array.new)
58
-
59
- if list.any?
60
- list.each { |c| c.call(self, *args, &block) }
61
- end
62
- end
63
-
64
- def has_callback?(name)
65
- self.callbacks[name] && !self.callbacks[name].empty?
66
- end # has_callback?
67
- end # Callbacks
5
+ # backwards compatibility
6
+ # @private
7
+ Callbacks = Async::Callbacks
68
8
  end # Client
69
9
  end # AMQ
10
+
@@ -1,383 +1,11 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "amq/client/entity"
4
- require "amq/client/queue"
5
- require "amq/client/exchange"
3
+ require "amq/client/async/channel"
6
4
 
7
5
  module AMQ
8
6
  module Client
9
- class Channel
10
-
11
- #
12
- # Behaviors
13
- #
14
-
15
- extend RegisterEntityMixin
16
- include Entity
17
- extend ProtocolMethodHandlers
18
-
19
- register_entity :queue, AMQ::Client::Queue
20
- register_entity :exchange, AMQ::Client::Exchange
21
-
22
- #
23
- # API
24
- #
25
-
26
-
27
- class ChannelOutOfBadError < StandardError # TODO: inherit from some AMQP error class defined in amq-protocol or use it straight away.
28
- def initialize(max, given)
29
- super("Channel max is #{max}, #{given} given.")
30
- end
31
- end
32
-
33
-
34
- DEFAULT_REPLY_TEXT = "Goodbye".freeze
35
-
36
- attr_reader :id
37
-
38
- attr_reader :exchanges_awaiting_declare_ok, :exchanges_awaiting_delete_ok
39
- attr_reader :queues_awaiting_declare_ok, :queues_awaiting_delete_ok, :queues_awaiting_bind_ok, :queues_awaiting_unbind_ok, :queues_awaiting_purge_ok, :queues_awaiting_consume_ok, :queues_awaiting_cancel_ok, :queues_awaiting_get_response
40
-
41
- attr_accessor :flow_is_active
42
-
43
-
44
- def initialize(connection, id)
45
- super(connection)
46
-
47
- @id = id
48
- @exchanges = Hash.new
49
- @queues = Hash.new
50
- @consumers = Hash.new
51
-
52
- reset_state!
53
-
54
- # 65536 is here for cases when channel is opened without passing a callback in,
55
- # otherwise channel_mix would be nil and it causes a lot of needless headaches.
56
- # lets just have this default. MK.
57
- channel_max = if @connection.open?
58
- @connection.channel_max || 65536
59
- else
60
- 65536
61
- end
62
-
63
- if channel_max != 0 && !(0..channel_max).include?(id)
64
- raise ChannelOutOfBadError.new(channel_max, id)
65
- end
66
- end
67
-
68
- def consumers
69
- @consumers
70
- end # consumers
71
-
72
- # @return [Array<Queue>] Collection of queues that were declared on this channel.
73
- def queues
74
- @queues.values
75
- end
76
-
77
- # @return [Array<Exchange>] Collection of exchanges that were declared on this channel.
78
- def exchanges
79
- @exchanges.values
80
- end
81
-
82
-
83
- # AMQP connection this channel belongs to.
84
- #
85
- # @return [AMQ::Client::Connection] Connection this channel belongs to.
86
- def connection
87
- @connection
88
- end # connection
89
-
90
-
91
- # @group Channel lifecycle
92
-
93
- # Opens AMQP channel.
94
- #
95
- # @api public
96
- def open(&block)
97
- @connection.send_frame(Protocol::Channel::Open.encode(@id, AMQ::Protocol::EMPTY_STRING))
98
- @connection.channels[@id] = self
99
- self.status = :opening
100
-
101
- self.redefine_callback :open, &block
102
- end
103
-
104
- # Closes AMQP channel.
105
- #
106
- # @api public
107
- def close(reply_code = 200, reply_text = DEFAULT_REPLY_TEXT, class_id = 0, method_id = 0, &block)
108
- @connection.send_frame(Protocol::Channel::Close.encode(@id, reply_code, reply_text, class_id, method_id))
109
-
110
- self.redefine_callback :close, &block
111
- end
112
-
113
- # @endgroup
114
-
115
-
116
-
117
- # @group Message acknowledgements
118
-
119
- # Acknowledge one or all messages on the channel.
120
- #
121
- # @api public
122
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.13.)
123
- def acknowledge(delivery_tag, multiple = false)
124
- @connection.send_frame(Protocol::Basic::Ack.encode(self.id, delivery_tag, multiple))
125
-
126
- self
127
- end # acknowledge(delivery_tag, multiple = false)
128
-
129
- # Reject a message with given delivery tag.
130
- #
131
- # @api public
132
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.14.)
133
- def reject(delivery_tag, requeue = true)
134
- @connection.send_frame(Protocol::Basic::Reject.encode(self.id, delivery_tag, requeue))
135
-
136
- self
137
- end # reject(delivery_tag, requeue = true)
138
-
139
- # Notifies AMQ broker that consumer has recovered and unacknowledged messages need
140
- # to be redelivered.
141
- #
142
- # @return [Channel] self
143
- #
144
- # @note RabbitMQ as of 2.3.1 does not support basic.recover with requeue = false.
145
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.8.3.16.)
146
- # @api public
147
- def recover(requeue = true, &block)
148
- @connection.send_frame(Protocol::Basic::Recover.encode(@id, requeue))
149
-
150
- self.redefine_callback :recover, &block
151
- self
152
- end # recover(requeue = false, &block)
153
-
154
- # @endgroup
155
-
156
-
157
-
158
- # @group QoS and flow handling
159
-
160
- # Requests a specific quality of service. The QoS can be specified for the current channel
161
- # or for all channels on the connection.
162
- #
163
- # @note RabbitMQ as of 2.3.1 does not support prefetch_size.
164
- # @api public
165
- def qos(prefetch_size = 0, prefetch_count = 32, global = false, &block)
166
- @connection.send_frame(Protocol::Basic::Qos.encode(@id, prefetch_size, prefetch_count, global))
167
-
168
- self.redefine_callback :qos, &block
169
- self
170
- end # qos(prefetch_size = 4096, prefetch_count = 32, global = false, &block)
171
-
172
- # Asks the peer to pause or restart the flow of content data sent to a consumer.
173
- # This is a simple flow­control mechanism that a peer can use to avoid overflowing its
174
- # queues or otherwise finding itself receiving more messages than it can process. Note that
175
- # this method is not intended for window control. It does not affect contents returned to
176
- # Queue#get callers.
177
- #
178
- # @param [Boolean] active Desired flow state.
179
- #
180
- # @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.5.2.3.)
181
- # @api public
182
- def flow(active = false, &block)
183
- @connection.send_frame(Protocol::Channel::Flow.encode(@id, active))
184
-
185
- self.redefine_callback :flow, &block
186
- self
187
- end # flow(active = false, &block)
188
-
189
- # @return [Boolean] True if flow in this channel is active (messages will be delivered to consumers that use this channel).
190
- #
191
- # @api public
192
- def flow_is_active?
193
- @flow_is_active
194
- end # flow_is_active?
195
-
196
- # @endgroup
197
-
198
-
199
-
200
- # @group Transactions
201
-
202
- # Sets the channel to use standard transactions. One must use this method at least
203
- # once on a channel before using #tx_tommit or tx_rollback methods.
204
- #
205
- # @api public
206
- def tx_select(&block)
207
- @connection.send_frame(Protocol::Tx::Select.encode(@id))
208
-
209
- self.redefine_callback :tx_select, &block
210
- self
211
- end # tx_select(&block)
212
-
213
- # Commits AMQP transaction.
214
- #
215
- # @api public
216
- def tx_commit(&block)
217
- @connection.send_frame(Protocol::Tx::Commit.encode(@id))
218
-
219
- self.redefine_callback :tx_commit, &block
220
- self
221
- end # tx_commit(&block)
222
-
223
- # Rolls AMQP transaction back.
224
- #
225
- # @api public
226
- def tx_rollback(&block)
227
- @connection.send_frame(Protocol::Tx::Rollback.encode(@id))
228
-
229
- self.redefine_callback :tx_rollback, &block
230
- self
231
- end # tx_rollback(&block)
232
-
233
- # @endgroup
234
-
235
-
236
-
237
- # @group Error handling
238
-
239
- # Defines a callback that will be executed when channel is closed after
240
- # channel-level exception.
241
- #
242
- # @api public
243
- def on_error(&block)
244
- self.define_callback(:error, &block)
245
- end
246
-
247
- # @endgroup
248
-
249
-
250
- #
251
- # Implementation
252
- #
253
-
254
- def register_exchange(exchange)
255
- raise ArgumentError, "argument is nil!" if exchange.nil?
256
-
257
- @exchanges[exchange.name] = exchange
258
- end # register_exchange(exchange)
259
-
260
- # Finds exchange in the exchanges cache on this channel by name. Exchange only exists in the cache if
261
- # it was previously instantiated on this channel.
262
- #
263
- # @param [String] name Exchange name
264
- # @return [AMQ::Client::Exchange] Exchange (if found)
265
- # @api plugin
266
- def find_exchange(name)
267
- @exchanges[name]
268
- end
269
-
270
- def register_queue(queue)
271
- raise ArgumentError, "argument is nil!" if queue.nil?
272
-
273
- @queues[queue.name] = queue
274
- end # register_queue(queue)
275
-
276
- def find_queue(name)
277
- @queues[name]
278
- end
279
-
280
-
281
- def reset_state!
282
- @flow_is_active = true
283
-
284
- @queues_awaiting_declare_ok = Array.new
285
- @exchanges_awaiting_declare_ok = Array.new
286
-
287
- @queues_awaiting_delete_ok = Array.new
288
-
289
- @exchanges_awaiting_delete_ok = Array.new
290
- @queues_awaiting_purge_ok = Array.new
291
- @queues_awaiting_bind_ok = Array.new
292
- @queues_awaiting_unbind_ok = Array.new
293
- @queues_awaiting_consume_ok = Array.new
294
- @queues_awaiting_cancel_ok = Array.new
295
-
296
- @queues_awaiting_get_response = Array.new
297
-
298
- @callbacks = Hash.new
299
- end # reset_state!
300
-
301
-
302
- def handle_connection_interruption(method = nil)
303
- self.reset_state!
304
- end # handle_connection_interruption
305
-
306
-
307
-
308
- def handle_open_ok(open_ok)
309
- self.status = :opened
310
- self.exec_callback_once_yielding_self(:open, open_ok)
311
- end
312
-
313
- def handle_close_ok(close_ok)
314
- self.status = :closed
315
- self.exec_callback_once_yielding_self(:close, close_ok)
316
- end
317
-
318
- def handle_close(channel_close)
319
- self.status = :closed
320
- self.exec_callback_yielding_self(:error, channel_close)
321
-
322
- self.handle_connection_interruption(channel_close)
323
- end
324
-
325
-
326
-
327
- self.handle(Protocol::Channel::OpenOk) do |connection, frame|
328
- channel = connection.channels[frame.channel]
329
- channel.handle_open_ok(frame.decode_payload)
330
- end
331
-
332
- self.handle(Protocol::Channel::CloseOk) do |connection, frame|
333
- method = frame.decode_payload
334
- channels = connection.channels
335
-
336
- channel = channels[frame.channel]
337
- channels.delete(channel)
338
- channel.handle_close_ok(method)
339
- end
340
-
341
- self.handle(Protocol::Channel::Close) do |connection, frame|
342
- method = frame.decode_payload
343
- channels = connection.channels
344
- channel = channels[frame.channel]
345
-
346
- channel.handle_close(method)
347
- end
348
-
349
- self.handle(Protocol::Basic::QosOk) do |connection, frame|
350
- channel = connection.channels[frame.channel]
351
- channel.exec_callback(:qos, frame.decode_payload)
352
- end
353
-
354
- self.handle(Protocol::Basic::RecoverOk) do |connection, frame|
355
- channel = connection.channels[frame.channel]
356
- channel.exec_callback(:recover, frame.decode_payload)
357
- end
358
-
359
- self.handle(Protocol::Channel::FlowOk) do |connection, frame|
360
- channel = connection.channels[frame.channel]
361
- method = frame.decode_payload
362
-
363
- channel.flow_is_active = method.active
364
- channel.exec_callback(:flow, method)
365
- end
366
-
367
- self.handle(Protocol::Tx::SelectOk) do |connection, frame|
368
- channel = connection.channels[frame.channel]
369
- channel.exec_callback(:tx_select, frame.decode_payload)
370
- end
371
-
372
- self.handle(Protocol::Tx::CommitOk) do |connection, frame|
373
- channel = connection.channels[frame.channel]
374
- channel.exec_callback(:tx_commit, frame.decode_payload)
375
- end
376
-
377
- self.handle(Protocol::Tx::RollbackOk) do |connection, frame|
378
- channel = connection.channels[frame.channel]
379
- channel.exec_callback(:tx_rollback, frame.decode_payload)
380
- end
381
- end # Channel
7
+ # backwards compatibility
8
+ # @private
9
+ Channel = Async::Channel
382
10
  end # Client
383
11
  end # AMQ