amqp 0.7.0.pre → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|