amqp 0.7.0.pre → 0.7.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.
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/CHANGELOG +8 -2
- data/CONTRIBUTORS +22 -0
- data/Gemfile +3 -3
- data/README.md +20 -11
- data/Rakefile +30 -6
- data/amqp.gemspec +1 -1
- data/bin/cleanify.rb +50 -0
- data/examples/amqp/simple.rb +6 -4
- data/examples/mq/ack.rb +8 -6
- data/examples/mq/automatic_binding_for_default_direct_exchange.rb +65 -0
- data/examples/mq/callbacks.rb +9 -1
- data/examples/mq/clock.rb +17 -17
- data/examples/mq/hashtable.rb +19 -10
- data/examples/mq/internal.rb +13 -11
- data/examples/mq/logger.rb +38 -36
- data/examples/mq/multiclock.rb +16 -7
- data/examples/mq/pingpong.rb +16 -7
- data/examples/mq/pop.rb +8 -6
- data/examples/mq/primes-simple.rb +2 -0
- data/examples/mq/primes.rb +7 -5
- data/examples/mq/stocks.rb +14 -5
- data/lib/amqp.rb +12 -8
- data/lib/amqp/buffer.rb +35 -158
- data/lib/amqp/client.rb +34 -22
- data/lib/amqp/frame.rb +8 -64
- data/lib/amqp/protocol.rb +21 -70
- data/lib/amqp/server.rb +11 -9
- data/lib/amqp/spec.rb +8 -6
- data/lib/amqp/version.rb +2 -0
- data/lib/ext/blankslate.rb +3 -1
- data/lib/ext/em.rb +2 -0
- data/lib/ext/emfork.rb +13 -11
- data/lib/mq.rb +253 -156
- data/lib/mq/collection.rb +6 -88
- data/lib/mq/exchange.rb +70 -13
- data/lib/mq/header.rb +12 -6
- data/lib/mq/logger.rb +9 -7
- data/lib/mq/queue.rb +42 -30
- data/lib/mq/rpc.rb +6 -4
- data/protocol/codegen.rb +20 -18
- data/research/api.rb +10 -46
- data/research/primes-forked.rb +9 -7
- data/research/primes-processes.rb +74 -72
- data/research/primes-threaded.rb +9 -7
- data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +61 -0
- data/spec/mq_helper.rb +70 -0
- data/spec/spec_helper.rb +84 -29
- data/spec/unit/amqp/buffer_spec.rb +178 -0
- data/spec/unit/amqp/client_spec.rb +472 -0
- data/spec/unit/amqp/frame_spec.rb +60 -0
- data/spec/unit/amqp/misc_spec.rb +123 -0
- data/spec/unit/amqp/protocol_spec.rb +53 -0
- data/spec/unit/mq/channel_close_spec.rb +15 -0
- data/spec/unit/mq/collection_spec.rb +129 -0
- data/spec/unit/mq/exchange_declaration_spec.rb +524 -0
- data/spec/unit/mq/misc_spec.rb +228 -0
- data/spec/unit/mq/mq_basic_spec.rb +39 -0
- data/spec/unit/mq/queue_declaration_spec.rb +97 -0
- data/spec/unit/mq/queue_spec.rb +71 -0
- metadata +33 -21
- data/Gemfile.lock +0 -16
- data/old/README +0 -30
- data/old/Rakefile +0 -12
- data/old/amqp-0.8.json +0 -606
- data/old/amqp_spec.rb +0 -796
- data/old/amqpc.rb +0 -695
- data/old/codegen.rb +0 -148
- data/spec/channel_close_spec.rb +0 -13
- data/spec/sync_async_spec.rb +0 -52
data/lib/mq/collection.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
class MQ
|
4
|
+
# MQ::Collection is used to store named AMQ model entities (exchanges, queues)
|
4
5
|
class Collection < ::Array
|
5
6
|
class IncompatibleItemError < ArgumentError
|
6
7
|
def initialize(item)
|
@@ -21,15 +22,17 @@ class MQ
|
|
21
22
|
# run declare twice in order to change options, because the AMQP
|
22
23
|
# broker closes the connection if we try to do so).
|
23
24
|
|
24
|
-
# Use Collection
|
25
|
+
# Use Collection# << for adding items to the collection.
|
25
26
|
undef_method :[]=
|
26
27
|
|
27
28
|
def <<(item)
|
28
|
-
if (item.name rescue nil).nil? || !
|
29
|
+
if (item.name rescue nil).nil? || !self[item.name]
|
29
30
|
self.add!(item)
|
30
31
|
end
|
31
32
|
|
32
|
-
return item
|
33
|
+
# We can't just return the item, because in case the item isn't added
|
34
|
+
# to the collection, then it'd be different from self[item.name].
|
35
|
+
return self[item.name]
|
33
36
|
end
|
34
37
|
|
35
38
|
alias_method :__push__, :push
|
@@ -45,88 +48,3 @@ class MQ
|
|
45
48
|
end
|
46
49
|
end
|
47
50
|
end
|
48
|
-
|
49
|
-
if $0 =~ /bacon/ or $0 == __FILE__
|
50
|
-
require "bacon"
|
51
|
-
|
52
|
-
Item = Struct.new(:name)
|
53
|
-
|
54
|
-
describe MQ::Collection do
|
55
|
-
before do
|
56
|
-
@items = 3.times.map { |int| Item.new("name-#{int}") }
|
57
|
-
@collection = MQ::Collection.new(@items)
|
58
|
-
end
|
59
|
-
|
60
|
-
describe "accessors" do
|
61
|
-
should "be accessible by its name" do
|
62
|
-
@collection["name-1"].should.not.be.nil
|
63
|
-
@collection["name-1"].should.eql(@items[1])
|
64
|
-
end
|
65
|
-
|
66
|
-
should "not allow to change already existing object" do
|
67
|
-
lambda { @collection["name-1"] = Item.new("test") }.should.raise(NoMethodError)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe "#<<" do
|
72
|
-
should "raise IncompatibleItemError if the argument doesn't have method :name" do
|
73
|
-
lambda { @collection << nil }.should.raise(MQ::Collection::IncompatibleItemError)
|
74
|
-
end
|
75
|
-
|
76
|
-
should "add an item into the collection" do
|
77
|
-
length = @collection.length
|
78
|
-
@collection << Item.new("test")
|
79
|
-
@collection.length.should.eql(length + 1)
|
80
|
-
end
|
81
|
-
|
82
|
-
should "not add an item to the collection if another item with given name already exists and the name IS NOT nil" do
|
83
|
-
@collection << Item.new("test")
|
84
|
-
length = @collection.length
|
85
|
-
@collection << Item.new("test")
|
86
|
-
@collection.length.should.eql(length)
|
87
|
-
end
|
88
|
-
|
89
|
-
should "add an item to the collection if another item with given name already exists and the name IS nil" do
|
90
|
-
@collection << Item.new(nil)
|
91
|
-
length = @collection.length
|
92
|
-
@collection << Item.new(nil)
|
93
|
-
@collection.length.should.eql(length + 1)
|
94
|
-
end
|
95
|
-
|
96
|
-
should "return the item" do
|
97
|
-
item = Item.new("test")
|
98
|
-
(@collection << item).should.eql item
|
99
|
-
end
|
100
|
-
|
101
|
-
should "return the item even if it already existed" do
|
102
|
-
item = Item.new("test")
|
103
|
-
@collection << item
|
104
|
-
(@collection << item).should.eql item
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe "#add!" do
|
109
|
-
should "raise IncompatibleItemError if the argument doesn't have method :name" do
|
110
|
-
lambda { @collection << nil }.should.raise(MQ::Collection::IncompatibleItemError)
|
111
|
-
end
|
112
|
-
|
113
|
-
should "add an item into the collection" do
|
114
|
-
length = @collection.length
|
115
|
-
@collection << Item.new("test")
|
116
|
-
@collection.length.should.eql(length + 1)
|
117
|
-
end
|
118
|
-
|
119
|
-
should "add an item to the collection if another item with given name already exists" do
|
120
|
-
@collection.add! Item.new("test")
|
121
|
-
length = @collection.length
|
122
|
-
@collection.add! Item.new("test")
|
123
|
-
@collection.length.should.eql(length + 1)
|
124
|
-
end
|
125
|
-
|
126
|
-
should "return the item" do
|
127
|
-
item = Item.new("test")
|
128
|
-
(@collection << item).should.eql item
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
data/lib/mq/exchange.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
class MQ
|
2
4
|
# An Exchange acts as an ingress point for all published messages. An
|
3
5
|
# exchange may also be described as a router or a matcher. Every
|
@@ -20,8 +22,41 @@ class MQ
|
|
20
22
|
# the default exchange for publishing the messages.
|
21
23
|
#
|
22
24
|
class Exchange
|
25
|
+
|
26
|
+
#
|
27
|
+
# Behaviors
|
28
|
+
#
|
29
|
+
|
23
30
|
include AMQP
|
24
31
|
|
32
|
+
|
33
|
+
|
34
|
+
#
|
35
|
+
# API
|
36
|
+
#
|
37
|
+
|
38
|
+
|
39
|
+
# The default exchange.
|
40
|
+
# Every queue is bind to this (direct) exchange by default.
|
41
|
+
# You can't remove it or bind there queue explicitly.
|
42
|
+
|
43
|
+
# Do NOT confuse with amq.direct: it's only a normal direct
|
44
|
+
# exchange and the only special thing about it is that it's
|
45
|
+
# predefined in the system, so you can use it straightaway.
|
46
|
+
|
47
|
+
# Example:
|
48
|
+
# MQ.new.queue("tasks")
|
49
|
+
# MQ::Exchange.default.publish("make clean", routing_key: "tasks")
|
50
|
+
|
51
|
+
# For more info see section 2.1.2.4 Automatic Mode of the AMQP 0.9.1 spec.
|
52
|
+
def self.default
|
53
|
+
@@default ||= self.new(MQ.new, :direct, "", :no_declare => true)
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.add_default_options(type, name, opts, block)
|
57
|
+
{ :exchange => name, :type => type, :nowait => block.nil? }.merge(opts)
|
58
|
+
end
|
59
|
+
|
25
60
|
# Defines, intializes and returns an Exchange to act as an ingress
|
26
61
|
# point for all published messages.
|
27
62
|
#
|
@@ -194,14 +229,15 @@ class MQ
|
|
194
229
|
# sensitive to the ordering of clients' actions!
|
195
230
|
#
|
196
231
|
# == Exceptions
|
197
|
-
# Doing any of these activities are illegal and will raise
|
198
|
-
#
|
232
|
+
# Doing any of these activities are illegal and will raise exceptions:
|
233
|
+
#
|
234
|
+
# * redeclare an already-declared exchange to a different type (raises MQ::IncompatibleOptionsError)
|
199
235
|
# * :passive => true and the exchange does not exist (NOT_FOUND)
|
200
236
|
#
|
201
|
-
def initialize
|
237
|
+
def initialize(mq, type, name, opts = {}, &block)
|
202
238
|
@mq = mq
|
203
239
|
@type, @opts = type, opts
|
204
|
-
@opts =
|
240
|
+
@opts = self.class.add_default_options(type, name, opts, block)
|
205
241
|
@key = opts[:key]
|
206
242
|
@name = name unless name.empty?
|
207
243
|
@status = :unknown
|
@@ -225,7 +261,7 @@ class MQ
|
|
225
261
|
# Call the callback immediately, as given exchange is already
|
226
262
|
# declared.
|
227
263
|
@status = :finished
|
228
|
-
block.call(self)
|
264
|
+
block.call(self) if block
|
229
265
|
end
|
230
266
|
|
231
267
|
self.callback = block
|
@@ -274,8 +310,8 @@ class MQ
|
|
274
310
|
# message stays in memory and is never persisted to non-volatile (slow)
|
275
311
|
# storage.
|
276
312
|
#
|
277
|
-
def publish
|
278
|
-
@mq.callback{
|
313
|
+
def publish(data, opts = {})
|
314
|
+
@mq.callback {
|
279
315
|
out = []
|
280
316
|
|
281
317
|
out << Protocol::Basic::Publish.new({ :exchange => name,
|
@@ -317,8 +353,8 @@ class MQ
|
|
317
353
|
# bindings. If the exchange has queue bindings the server does not
|
318
354
|
# delete it but raises a channel exception instead (MQ:Error).
|
319
355
|
#
|
320
|
-
def delete
|
321
|
-
@mq.callback{
|
356
|
+
def delete(opts = {})
|
357
|
+
@mq.callback {
|
322
358
|
@mq.send Protocol::Exchange::Delete.new({ :exchange => name,
|
323
359
|
:nowait => true }.merge(opts))
|
324
360
|
@mq.exchanges.delete name
|
@@ -326,13 +362,34 @@ class MQ
|
|
326
362
|
nil
|
327
363
|
end
|
328
364
|
|
365
|
+
|
366
|
+
def durable?
|
367
|
+
!!@opts[:durable]
|
368
|
+
end # durable?
|
369
|
+
|
370
|
+
def transient?
|
371
|
+
!self.durable?
|
372
|
+
end # transient?
|
373
|
+
|
374
|
+
def auto_deleted?
|
375
|
+
!!@opts[:auto_delete]
|
376
|
+
end # auto_deleted?
|
377
|
+
alias auto_deletable? auto_deleted?
|
378
|
+
|
379
|
+
|
329
380
|
def reset
|
330
381
|
@deferred_status = nil
|
331
382
|
initialize @mq, @type, @name, @opts
|
332
383
|
end
|
333
384
|
|
334
|
-
|
385
|
+
|
386
|
+
|
387
|
+
#
|
388
|
+
# Implementation
|
389
|
+
#
|
390
|
+
|
391
|
+
def receive_response(response)
|
335
392
|
self.callback && self.callback.call(self)
|
336
|
-
end
|
337
|
-
end
|
338
|
-
end
|
393
|
+
end # receive_response
|
394
|
+
end # Exchange
|
395
|
+
end # MQ
|
data/lib/mq/header.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
class MQ
|
2
4
|
class Header
|
3
5
|
include AMQP
|
@@ -9,20 +11,24 @@ class MQ
|
|
9
11
|
|
10
12
|
# Acknowledges the receipt of this message with the server.
|
11
13
|
def ack
|
12
|
-
@mq.callback{
|
14
|
+
@mq.callback {
|
13
15
|
@mq.send Protocol::Basic::Ack.new(:delivery_tag => properties[:delivery_tag])
|
14
16
|
}
|
15
17
|
end
|
16
18
|
|
17
19
|
# Reject this message (XXX currently unimplemented in rabbitmq)
|
18
20
|
# * :requeue => true | false (default false)
|
19
|
-
def reject
|
20
|
-
@mq.
|
21
|
-
|
22
|
-
|
21
|
+
def reject(opts = {})
|
22
|
+
if @mq.broker.server_properties[:product] == "RabbitMQ"
|
23
|
+
raise NotImplementedError.new("RabbitMQ doesn't implement the Basic.Reject method\nSee http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2009-February/002853.html")
|
24
|
+
else
|
25
|
+
@mq.callback {
|
26
|
+
@mq.send Protocol::Basic::Reject.new(opts.merge(:delivery_tag => properties[:delivery_tag]))
|
27
|
+
}
|
28
|
+
end
|
23
29
|
end
|
24
30
|
|
25
|
-
def method_missing
|
31
|
+
def method_missing(meth, *args, &blk)
|
26
32
|
@header.send meth, *args, &blk
|
27
33
|
end
|
28
34
|
|
data/lib/mq/logger.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
class MQ
|
2
4
|
class Logger
|
3
|
-
def initialize
|
5
|
+
def initialize(*args, &block)
|
4
6
|
opts = args.pop if args.last.is_a? Hash
|
5
7
|
opts ||= {}
|
6
8
|
|
@@ -13,7 +15,7 @@ class MQ
|
|
13
15
|
attr_reader :prop
|
14
16
|
alias :base :prop
|
15
17
|
|
16
|
-
def log
|
18
|
+
def log(severity, *args)
|
17
19
|
opts = args.pop if args.last.is_a? Hash and args.size != 1
|
18
20
|
opts ||= {}
|
19
21
|
opts = @prop.clone.update(opts)
|
@@ -56,7 +58,7 @@ class MQ
|
|
56
58
|
end
|
57
59
|
alias :method_missing :log
|
58
60
|
|
59
|
-
def print
|
61
|
+
def print(data = nil, &block)
|
60
62
|
if block
|
61
63
|
@printer = block
|
62
64
|
elsif data.is_a? Proc
|
@@ -68,7 +70,7 @@ class MQ
|
|
68
70
|
end
|
69
71
|
end
|
70
72
|
alias :printer :print
|
71
|
-
|
73
|
+
|
72
74
|
def self.printer &block
|
73
75
|
@printer = block if block
|
74
76
|
@printer
|
@@ -77,13 +79,13 @@ class MQ
|
|
77
79
|
def self.disabled?
|
78
80
|
!!@disabled
|
79
81
|
end
|
80
|
-
|
82
|
+
|
81
83
|
def self.enable
|
82
84
|
@disabled = false
|
83
85
|
end
|
84
|
-
|
86
|
+
|
85
87
|
def self.disable
|
86
88
|
@disabled = true
|
87
89
|
end
|
88
90
|
end
|
89
|
-
end
|
91
|
+
end
|
data/lib/mq/queue.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
class MQ
|
2
4
|
class Queue
|
3
5
|
include AMQP
|
4
6
|
|
7
|
+
def self.add_default_options(name, opts, block)
|
8
|
+
{ :queue => name, :nowait => block.nil? }.merge(opts)
|
9
|
+
end
|
10
|
+
|
5
11
|
# Queues store and forward messages. Queues can be configured in the server
|
6
12
|
# or created at runtime. Queues must be attached to at least one exchange
|
7
13
|
# in order to receive messages from publishers.
|
@@ -15,8 +21,8 @@ class MQ
|
|
15
21
|
#
|
16
22
|
# == Options
|
17
23
|
# * :passive => true | false (default false)
|
18
|
-
# If set, the server will not create the
|
19
|
-
# already exist. The client can use this to check whether
|
24
|
+
# If set, the server will not create the queue if it does not
|
25
|
+
# already exist. The client can use this to check whether the queue
|
20
26
|
# exists without modifying the server state.
|
21
27
|
#
|
22
28
|
# * :durable => true | false (default false)
|
@@ -51,7 +57,7 @@ class MQ
|
|
51
57
|
#
|
52
58
|
# The server waits for a short period of time before
|
53
59
|
# determining the queue is unused to give time to the client code
|
54
|
-
# to bind
|
60
|
+
# to bind a queue to it.
|
55
61
|
#
|
56
62
|
# If the queue has been previously declared, this option is ignored
|
57
63
|
# on subsequent declarations.
|
@@ -61,9 +67,9 @@ class MQ
|
|
61
67
|
# not wait for a reply method. If the server could not complete the
|
62
68
|
# method it will raise a channel or connection exception.
|
63
69
|
#
|
64
|
-
def initialize
|
70
|
+
def initialize(mq, name, opts = {}, &block)
|
65
71
|
@mq = mq
|
66
|
-
@opts =
|
72
|
+
@opts = self.class.add_default_options(name, opts, block)
|
67
73
|
@bindings ||= {}
|
68
74
|
@name = name unless name.empty?
|
69
75
|
@status = @opts[:nowait] ? :unknown : :unfinished
|
@@ -74,7 +80,7 @@ class MQ
|
|
74
80
|
self.callback = block
|
75
81
|
end
|
76
82
|
|
77
|
-
attr_reader :name
|
83
|
+
attr_reader :name, :sync_bind
|
78
84
|
attr_accessor :opts, :callback, :bind_callback
|
79
85
|
|
80
86
|
# This method binds a queue to an exchange. Until a queue is
|
@@ -110,12 +116,13 @@ class MQ
|
|
110
116
|
# not wait for a reply method. If the server could not complete the
|
111
117
|
# method it will raise a channel or connection exception.
|
112
118
|
#
|
113
|
-
def bind
|
119
|
+
def bind(exchange, opts = {}, &block)
|
114
120
|
@status = :unbound
|
121
|
+
@sync_bind = ! opts[:nowait]
|
115
122
|
exchange = exchange.respond_to?(:name) ? exchange.name : exchange
|
116
123
|
@bindings[exchange] = opts
|
117
124
|
|
118
|
-
@mq.callback{
|
125
|
+
@mq.callback {
|
119
126
|
@mq.send Protocol::Queue::Bind.new({ :queue => name,
|
120
127
|
:exchange => exchange,
|
121
128
|
:routing_key => opts[:key],
|
@@ -139,11 +146,11 @@ class MQ
|
|
139
146
|
# not wait for a reply method. If the server could not complete the
|
140
147
|
# method it will raise a channel or connection exception.
|
141
148
|
#
|
142
|
-
def unbind
|
149
|
+
def unbind(exchange, opts = {})
|
143
150
|
exchange = exchange.respond_to?(:name) ? exchange.name : exchange
|
144
151
|
@bindings.delete exchange
|
145
152
|
|
146
|
-
@mq.callback{
|
153
|
+
@mq.callback {
|
147
154
|
@mq.send Protocol::Queue::Unbind.new({ :queue => name,
|
148
155
|
:exchange => exchange,
|
149
156
|
:routing_key => opts[:key],
|
@@ -172,8 +179,8 @@ class MQ
|
|
172
179
|
# not wait for a reply method. If the server could not complete the
|
173
180
|
# method it will raise a channel or connection exception.
|
174
181
|
#
|
175
|
-
def delete
|
176
|
-
@mq.callback{
|
182
|
+
def delete(opts = {})
|
183
|
+
@mq.callback {
|
177
184
|
@mq.send Protocol::Queue::Delete.new({ :queue => name,
|
178
185
|
:nowait => true }.merge(opts))
|
179
186
|
}
|
@@ -183,8 +190,8 @@ class MQ
|
|
183
190
|
|
184
191
|
# Purge all messages from the queue.
|
185
192
|
#
|
186
|
-
def purge
|
187
|
-
@mq.callback{
|
193
|
+
def purge(opts = {})
|
194
|
+
@mq.callback {
|
188
195
|
@mq.send Protocol::Queue::Purge.new({ :queue => name,
|
189
196
|
:nowait => true }.merge(opts))
|
190
197
|
}
|
@@ -245,14 +252,14 @@ class MQ
|
|
245
252
|
# not wait for a reply method. If the server could not complete the
|
246
253
|
# method it will raise a channel or connection exception.
|
247
254
|
#
|
248
|
-
def pop
|
255
|
+
def pop(opts = {}, &blk)
|
249
256
|
if blk
|
250
257
|
@on_pop = blk
|
251
258
|
@on_pop_opts = opts
|
252
259
|
end
|
253
260
|
|
254
|
-
@mq.callback{
|
255
|
-
@mq.get_queue{ |q|
|
261
|
+
@mq.callback {
|
262
|
+
@mq.get_queue { |q|
|
256
263
|
q.push(self)
|
257
264
|
@mq.send Protocol::Basic::Get.new({ :queue => name,
|
258
265
|
:consumer_tag => name,
|
@@ -318,7 +325,7 @@ class MQ
|
|
318
325
|
# automatically set :nowait => false. This is required for the server
|
319
326
|
# to send a confirmation.
|
320
327
|
#
|
321
|
-
def subscribe
|
328
|
+
def subscribe(opts = {}, &blk)
|
322
329
|
@consumer_tag = "#{name}-#{Kernel.rand(999_999_999_999)}"
|
323
330
|
@mq.consumers[@consumer_tag] = self
|
324
331
|
|
@@ -328,7 +335,7 @@ class MQ
|
|
328
335
|
@on_msg_opts = opts
|
329
336
|
opts[:nowait] = false if (@on_confirm_subscribe = opts[:confirm])
|
330
337
|
|
331
|
-
@mq.callback{
|
338
|
+
@mq.callback {
|
332
339
|
@mq.send Protocol::Basic::Consume.new({ :queue => name,
|
333
340
|
:consumer_tag => @consumer_tag,
|
334
341
|
:no_ack => !opts[:ack],
|
@@ -358,15 +365,15 @@ class MQ
|
|
358
365
|
# not wait for a reply method. If the server could not complete the
|
359
366
|
# method it will raise a channel or connection exception.
|
360
367
|
#
|
361
|
-
def unsubscribe
|
368
|
+
def unsubscribe(opts = {}, &blk)
|
362
369
|
@on_cancel = blk
|
363
|
-
@mq.callback{
|
370
|
+
@mq.callback {
|
364
371
|
@mq.send Protocol::Basic::Cancel.new({ :consumer_tag => @consumer_tag }.merge(opts))
|
365
372
|
}
|
366
373
|
self
|
367
374
|
end
|
368
375
|
|
369
|
-
def publish
|
376
|
+
def publish(data, opts = {})
|
370
377
|
exchange.publish(data, opts)
|
371
378
|
end
|
372
379
|
|
@@ -390,7 +397,7 @@ class MQ
|
|
390
397
|
# See AMQP::Protocol::Header for the hash properties available from
|
391
398
|
# the headers parameter. See #pop or #subscribe for a code example.
|
392
399
|
#
|
393
|
-
def receive
|
400
|
+
def receive(headers, body)
|
394
401
|
headers = MQ::Header.new(@mq, headers) unless headers.nil?
|
395
402
|
|
396
403
|
if cb = (@on_msg || @on_pop)
|
@@ -400,27 +407,32 @@ class MQ
|
|
400
407
|
|
401
408
|
# Get the number of messages and consumers on a queue.
|
402
409
|
#
|
403
|
-
# MQ.queue('name').status{ |num_messages, num_consumers|
|
410
|
+
# MQ.queue('name').status { |num_messages, num_consumers|
|
404
411
|
# puts num_messages
|
405
412
|
# }
|
406
413
|
#
|
407
|
-
def status
|
414
|
+
def status(opts = {}, &blk)
|
408
415
|
return @status if opts.empty? && blk.nil?
|
409
416
|
|
410
417
|
@on_status = blk
|
411
|
-
@mq.callback{
|
418
|
+
@mq.callback {
|
412
419
|
@mq.send Protocol::Queue::Declare.new({ :queue => name,
|
413
420
|
:passive => true }.merge(opts))
|
414
421
|
}
|
415
422
|
self
|
416
423
|
end
|
417
424
|
|
418
|
-
def receive_status
|
425
|
+
def receive_status(declare_ok)
|
419
426
|
@name = declare_ok.queue
|
420
427
|
@status = :finished
|
421
428
|
|
422
429
|
if self.callback
|
423
|
-
|
430
|
+
# compatibility for a common case when callback only takes one argument
|
431
|
+
if self.callback.arity == 1
|
432
|
+
self.callback.call(self)
|
433
|
+
else
|
434
|
+
self.callback.call(self, declare_ok.message_count, declare_ok.consumer_count)
|
435
|
+
end
|
424
436
|
end
|
425
437
|
|
426
438
|
if @on_status
|
@@ -430,7 +442,7 @@ class MQ
|
|
430
442
|
end
|
431
443
|
end
|
432
444
|
|
433
|
-
def after_bind
|
445
|
+
def after_bind(bind_ok)
|
434
446
|
@status = :bound
|
435
447
|
if self.bind_callback
|
436
448
|
self.bind_callback.call(self)
|
@@ -456,7 +468,7 @@ class MQ
|
|
456
468
|
|
457
469
|
binds = @bindings
|
458
470
|
@bindings = {}
|
459
|
-
binds.each{|ex,opts| bind(ex, opts) }
|
471
|
+
binds.each { |ex, opts| bind(ex, opts) }
|
460
472
|
|
461
473
|
if blk = @on_msg
|
462
474
|
@on_msg = nil
|