bunny 0.9.0.pre4 → 0.9.0.pre5
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/ChangeLog.md +30 -0
- data/README.md +1 -1
- data/examples/guides/exchanges/direct_exchange_routing.rb +36 -0
- data/examples/guides/exchanges/fanout_exchange_routing.rb +28 -0
- data/examples/guides/exchanges/headers_exchange_routing.rb +31 -0
- data/examples/guides/exchanges/mandatory_messages.rb +30 -0
- data/examples/guides/extensions/alternate_exchange.rb +28 -0
- data/examples/guides/extensions/basic_nack.rb +33 -0
- data/examples/guides/extensions/consumer_cancellation_notification.rb +39 -0
- data/examples/guides/extensions/dead_letter_exchange.rb +32 -0
- data/examples/guides/extensions/exchange_to_exchange_bindings.rb +29 -0
- data/examples/guides/extensions/per_message_ttl.rb +36 -0
- data/examples/guides/extensions/per_queue_message_ttl.rb +36 -0
- data/examples/guides/extensions/publisher_confirms.rb +28 -0
- data/examples/guides/extensions/queue_lease.rb +26 -0
- data/examples/guides/extensions/sender_selected_distribution.rb +32 -0
- data/lib/bunny/channel.rb +13 -1
- data/lib/bunny/consumer.rb +1 -1
- data/lib/bunny/exchange.rb +1 -0
- data/lib/bunny/queue.rb +1 -0
- data/lib/bunny/session.rb +0 -5
- data/lib/bunny/version.rb +1 -1
- data/spec/higher_level_api/integration/basic_return_spec.rb +1 -1
- data/spec/higher_level_api/integration/dead_lettering_spec.rb +52 -0
- data/spec/higher_level_api/integration/exchange_delete_spec.rb +2 -0
- data/spec/higher_level_api/integration/queue_delete_spec.rb +2 -0
- data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +36 -0
- data/spec/issues/issue83_spec.rb +31 -0
- metadata +22 -2
data/ChangeLog.md
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
## Changes between Bunny 0.9.0.pre4 and 0.9.0.pre5
|
2
|
+
|
3
|
+
### Channel Errors Reset
|
4
|
+
|
5
|
+
Channel error information is now properly reset when a channel is (re)opened.
|
6
|
+
|
7
|
+
GH issue: #83.
|
8
|
+
|
9
|
+
### Bunny::Consumer#initial Default Change
|
10
|
+
|
11
|
+
the default value of `Bunny::Consumer` noack argument changed from false to true
|
12
|
+
for consistency.
|
13
|
+
|
14
|
+
### Bunny::Session#prefetch Removed
|
15
|
+
|
16
|
+
Global prefetch is not implemented in RabbitMQ, so `Bunny::Session#prefetch`
|
17
|
+
is gone from the API.
|
18
|
+
|
19
|
+
### Queue Redeclaration Bug Fix
|
20
|
+
|
21
|
+
Fixed a problem when a queue was not declared after being deleted and redeclared
|
22
|
+
|
23
|
+
GH issue: #80
|
24
|
+
|
25
|
+
### Channel Cache Invalidation
|
26
|
+
|
27
|
+
Channel queue and exchange caches are now properly invalidated when queues and
|
28
|
+
exchanges are deleted.
|
29
|
+
|
30
|
+
|
1
31
|
## Changes between Bunny 0.9.0.pre3 and 0.9.0.pre4
|
2
32
|
|
3
33
|
### Heartbeats Support Fixes
|
data/README.md
CHANGED
@@ -37,7 +37,7 @@ gem install bunny --pre
|
|
37
37
|
To use Bunny 0.9.x in a project managed with Bundler:
|
38
38
|
|
39
39
|
``` ruby
|
40
|
-
gem "bunny", ">= 0.9.0.
|
40
|
+
gem "bunny", ">= 0.9.0.pre4" # optionally: , :git => "git://github.com/ruby-amqp/bunny.git", :branch => "master"
|
41
41
|
```
|
42
42
|
|
43
43
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Direct exchange routing"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x = ch.direct("examples.imaging")
|
15
|
+
|
16
|
+
q1 = ch.queue("", :auto_delete => true).bind(x, :routing_key => "resize")
|
17
|
+
q1.subscribe do |delivery_info, properties, payload|
|
18
|
+
puts "[consumer] #{q1.name} received a 'resize' message"
|
19
|
+
end
|
20
|
+
q2 = ch.queue("", :auto_delete => true).bind(x, :routing_key => "watermark")
|
21
|
+
q2.subscribe do |delivery_info, properties, payload|
|
22
|
+
puts "[consumer] #{q2.name} received a 'watermark' message"
|
23
|
+
end
|
24
|
+
|
25
|
+
# just an example
|
26
|
+
data = rand.to_s
|
27
|
+
x.publish(data, :routing_key => "resize")
|
28
|
+
x.publish(data, :routing_key => "watermark")
|
29
|
+
|
30
|
+
sleep 0.5
|
31
|
+
x.delete
|
32
|
+
q1.delete
|
33
|
+
q2.delete
|
34
|
+
|
35
|
+
puts "Disconnecting..."
|
36
|
+
conn.close
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Fanout exchange routing"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x = ch.fanout("examples.pings")
|
15
|
+
|
16
|
+
10.times do |i|
|
17
|
+
q = ch.queue("", :auto_delete => true).bind(x)
|
18
|
+
q.subscribe do |delivery_info, properties, payload|
|
19
|
+
puts "[consumer] #{q.name} received a message: #{payload}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
x.publish("Ping")
|
24
|
+
|
25
|
+
sleep 0.5
|
26
|
+
x.delete
|
27
|
+
puts "Disconnecting..."
|
28
|
+
conn.close
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Headers exchange routing"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x = ch.headers("headers")
|
15
|
+
|
16
|
+
q1 = ch.queue("", :exclusive => true).bind(x, :arguments => {"os" => "linux", "cores" => 8, "x-match" => "all"})
|
17
|
+
q2 = ch.queue("", :exclusive => true).bind(x, :arguments => {"os" => "osx", "cores" => 4, "x-match" => "any"})
|
18
|
+
|
19
|
+
q1.subscribe do |delivery_info, properties, content|
|
20
|
+
puts "#{q1.name} received #{content}"
|
21
|
+
end
|
22
|
+
q2.subscribe do |delivery_info, properties, content|
|
23
|
+
puts "#{q2.name} received #{content}"
|
24
|
+
end
|
25
|
+
|
26
|
+
x.publish("8 cores/Linux", :headers => {"os" => "linux", "cores" => 8})
|
27
|
+
x.publish("8 cores/OS X", :headers => {"os" => "osx", "cores" => 8})
|
28
|
+
x.publish("4 cores/Linux", :headers => {"os" => "linux", "cores" => 4})
|
29
|
+
|
30
|
+
sleep 0.5
|
31
|
+
conn.close
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Publishing messages as mandatory"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x = ch.default_exchange
|
15
|
+
|
16
|
+
x.on_return do |return_info, properties, content|
|
17
|
+
puts "Got a returned message: #{content}"
|
18
|
+
end
|
19
|
+
|
20
|
+
q = ch.queue("", :exclusive => true)
|
21
|
+
q.subscribe do |delivery_info, properties, content|
|
22
|
+
puts "Consumed a message: #{content}"
|
23
|
+
end
|
24
|
+
|
25
|
+
x.publish("This will NOT be returned", :mandatory => true, :routing_key => q.name)
|
26
|
+
x.publish("This will be returned", :mandatory => true, :routing_key => "akjhdfkjsh#{rand}")
|
27
|
+
|
28
|
+
sleep 0.5
|
29
|
+
puts "Disconnecting..."
|
30
|
+
conn.close
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating alternate exchanges"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x1 = ch.fanout("bunny.examples.ae.exchange1", :auto_delete => true, :durable => false)
|
15
|
+
x2 = ch.fanout("bunny.examples.ae.exchange2", :auto_delete => true, :durable => false, :arguments => {
|
16
|
+
"alternate-exchange" => x1.name
|
17
|
+
})
|
18
|
+
q = ch.queue("", :exclusive => true)
|
19
|
+
q.bind(x1)
|
20
|
+
|
21
|
+
x2.publish("")
|
22
|
+
|
23
|
+
sleep 0.2
|
24
|
+
puts "Queue #{q.name} now has #{q.message_count} message in it"
|
25
|
+
|
26
|
+
sleep 0.7
|
27
|
+
puts "Disconnecting..."
|
28
|
+
conn.close
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating basic.nack"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
q = ch.queue("", :exclusive => true)
|
15
|
+
|
16
|
+
20.times do
|
17
|
+
q.publish("")
|
18
|
+
end
|
19
|
+
|
20
|
+
20.times do
|
21
|
+
delivery_info, _, _ = q.pop(:ack => true)
|
22
|
+
|
23
|
+
if delivery_info.delivery_tag == 20
|
24
|
+
# requeue them all at once with basic.nack
|
25
|
+
ch.nack(delivery_info.delivery_tag, true, true)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
puts "Queue #{q.name} still has #{q.message_count} messages in it"
|
30
|
+
|
31
|
+
sleep 0.7
|
32
|
+
puts "Disconnecting..."
|
33
|
+
conn.close
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating consumer cancellation notification"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
|
15
|
+
module Bunny
|
16
|
+
module Examples
|
17
|
+
class ExampleConsumer < Bunny::Consumer
|
18
|
+
def cancelled?
|
19
|
+
@cancelled
|
20
|
+
end
|
21
|
+
|
22
|
+
def handle_cancellation(basic_cancel)
|
23
|
+
puts "#{@consumer_tag} was cancelled"
|
24
|
+
@cancelled = true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
q = ch.queue("", :exclusive => true)
|
31
|
+
c = Bunny::Examples::ExampleConsumer.new(ch, q)
|
32
|
+
q.subscribe_with(c)
|
33
|
+
|
34
|
+
sleep 0.1
|
35
|
+
q.delete
|
36
|
+
|
37
|
+
sleep 0.1
|
38
|
+
puts "Disconnecting..."
|
39
|
+
conn.close
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating dead letter exchange"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x = ch.fanout("amq.fanout")
|
15
|
+
dlx = ch.fanout("bunny.examples.dlx.exchange")
|
16
|
+
q = ch.queue("", :exclusive => true, :arguments => {"x-dead-letter-exchange" => dlx.name}).bind(x)
|
17
|
+
# dead letter queue
|
18
|
+
dlq = ch.queue("", :exclusive => true).bind(dlx)
|
19
|
+
|
20
|
+
x.publish("")
|
21
|
+
sleep 0.2
|
22
|
+
|
23
|
+
delivery_info, _, _ = q.pop(:ack => true)
|
24
|
+
puts "#{dlq.message_count} messages dead lettered so far"
|
25
|
+
puts "Rejecting a message"
|
26
|
+
ch.nack(delivery_info.delivery_tag, false)
|
27
|
+
sleep 0.2
|
28
|
+
puts "#{dlq.message_count} messages dead lettered so far"
|
29
|
+
|
30
|
+
dlx.delete
|
31
|
+
puts "Disconnecting..."
|
32
|
+
conn.close
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating exchange-to-exchange bindings"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x1 = ch.fanout("bunny.examples.e2e.exchange1", :auto_delete => true, :durable => false)
|
15
|
+
x2 = ch.fanout("bunny.examples.e2e.exchange2", :auto_delete => true, :durable => false)
|
16
|
+
# x1 will be the source
|
17
|
+
x2.bind(x1)
|
18
|
+
|
19
|
+
q = ch.queue("", :exclusive => true)
|
20
|
+
q.bind(x2)
|
21
|
+
|
22
|
+
x1.publish("")
|
23
|
+
|
24
|
+
sleep 0.2
|
25
|
+
puts "Queue #{q.name} now has #{q.message_count} message in it"
|
26
|
+
|
27
|
+
sleep 0.7
|
28
|
+
puts "Disconnecting..."
|
29
|
+
conn.close
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating per-message TTL"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x = ch.fanout("amq.fanout")
|
15
|
+
q = ch.queue("", :exclusive => true).bind(x)
|
16
|
+
|
17
|
+
10.times do |i|
|
18
|
+
x.publish("Message #{i}", :expiration => 1000)
|
19
|
+
end
|
20
|
+
|
21
|
+
sleep 0.7
|
22
|
+
_, _, content1 = q.pop
|
23
|
+
puts "Fetched #{content1.inspect} after 0.7 second"
|
24
|
+
|
25
|
+
sleep 0.8
|
26
|
+
_, _, content2 = q.pop
|
27
|
+
msg = if content2
|
28
|
+
content2.inspect
|
29
|
+
else
|
30
|
+
"nothing"
|
31
|
+
end
|
32
|
+
puts "Fetched #{msg} after 1.5 second"
|
33
|
+
|
34
|
+
sleep 0.7
|
35
|
+
puts "Closing..."
|
36
|
+
conn.close
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating per-queue message TTL"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x = ch.fanout("amq.fanout")
|
15
|
+
q = ch.queue("", :exclusive => true, :arguments => {"x-message-ttl" => 1000}).bind(x)
|
16
|
+
|
17
|
+
10.times do |i|
|
18
|
+
x.publish("Message #{i}")
|
19
|
+
end
|
20
|
+
|
21
|
+
sleep 0.7
|
22
|
+
_, _, content1 = q.pop
|
23
|
+
puts "Fetched #{content1.inspect} after 0.7 second"
|
24
|
+
|
25
|
+
sleep 0.8
|
26
|
+
_, _, content2 = q.pop
|
27
|
+
msg = if content2
|
28
|
+
content2.inspect
|
29
|
+
else
|
30
|
+
"nothing"
|
31
|
+
end
|
32
|
+
puts "Fetched #{msg} after 1.5 second"
|
33
|
+
|
34
|
+
sleep 0.7
|
35
|
+
puts "Closing..."
|
36
|
+
conn.close
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating publisher confirms"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x = ch.fanout("amq.fanout")
|
15
|
+
q = ch.queue("", :exclusive => true).bind(x)
|
16
|
+
|
17
|
+
ch.confirm_select
|
18
|
+
1000.times do
|
19
|
+
x.publish("")
|
20
|
+
end
|
21
|
+
ch.wait_for_confirms # blocks calling thread until all acks are received
|
22
|
+
|
23
|
+
sleep 0.2
|
24
|
+
puts "Received acks for all published messages. #{q.name} now has #{q.message_count} messages."
|
25
|
+
|
26
|
+
sleep 0.7
|
27
|
+
puts "Disconnecting..."
|
28
|
+
conn.close
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating queue TTL (queue leases)"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
q = ch.queue("", :exclusive => true, :arguments => {"x-expires" => 300})
|
15
|
+
|
16
|
+
sleep 0.4
|
17
|
+
begin
|
18
|
+
# this will raise because the queue is already deleted
|
19
|
+
q.message_count
|
20
|
+
rescue Bunny::NotFound => nfe
|
21
|
+
puts "Got a 404 response: the queue has already been removed"
|
22
|
+
end
|
23
|
+
|
24
|
+
sleep 0.7
|
25
|
+
puts "Closing..."
|
26
|
+
conn.close
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bunny"
|
6
|
+
|
7
|
+
puts "=> Demonstrating sender-selected distribution"
|
8
|
+
puts
|
9
|
+
|
10
|
+
conn = Bunny.new
|
11
|
+
conn.start
|
12
|
+
|
13
|
+
ch = conn.create_channel
|
14
|
+
x = ch.direct("bunny.examples.ssd.exchange")
|
15
|
+
q1 = ch.queue("", :exclusive => true).bind(x, :routing_key => "one")
|
16
|
+
q2 = ch.queue("", :exclusive => true).bind(x, :routing_key => "two")
|
17
|
+
q3 = ch.queue("", :exclusive => true).bind(x, :routing_key => "three")
|
18
|
+
q4 = ch.queue("", :exclusive => true).bind(x, :routing_key => "four")
|
19
|
+
|
20
|
+
10.times do |i|
|
21
|
+
x.publish("Message #{i}", :routing_key => "one", :headers => {"CC" => ["two", "three"]})
|
22
|
+
end
|
23
|
+
|
24
|
+
sleep 0.2
|
25
|
+
puts "Queue #{q1.name} now has #{q1.message_count} messages in it"
|
26
|
+
puts "Queue #{q2.name} now has #{q2.message_count} messages in it"
|
27
|
+
puts "Queue #{q3.name} now has #{q3.message_count} messages in it"
|
28
|
+
puts "Queue #{q4.name} now has #{q4.message_count} messages in it"
|
29
|
+
|
30
|
+
sleep 0.7
|
31
|
+
puts "Closing..."
|
32
|
+
conn.close
|
data/lib/bunny/channel.rb
CHANGED
@@ -18,7 +18,7 @@ module Bunny
|
|
18
18
|
#
|
19
19
|
|
20
20
|
attr_accessor :id, :connection, :status, :work_pool
|
21
|
-
attr_reader :next_publish_seq_no
|
21
|
+
attr_reader :next_publish_seq_no, :queues, :exchanges
|
22
22
|
|
23
23
|
|
24
24
|
def initialize(connection = nil, id = nil, work_pool = ConsumerWorkPool.new(1))
|
@@ -47,6 +47,9 @@ module Bunny
|
|
47
47
|
|
48
48
|
def open
|
49
49
|
@connection.open_channel(self)
|
50
|
+
# clear last channel error
|
51
|
+
@last_channel_error = nil
|
52
|
+
|
50
53
|
@status = :open
|
51
54
|
|
52
55
|
self
|
@@ -593,6 +596,7 @@ module Bunny
|
|
593
596
|
@only_acks_received
|
594
597
|
end
|
595
598
|
|
599
|
+
|
596
600
|
#
|
597
601
|
# Implementation
|
598
602
|
#
|
@@ -735,6 +739,10 @@ module Bunny
|
|
735
739
|
def synchronize(&block)
|
736
740
|
@publishing_mutex.synchronize(&block)
|
737
741
|
end
|
742
|
+
|
743
|
+
def deregister_queue(queue)
|
744
|
+
@queues.delete(queue.name)
|
745
|
+
end
|
738
746
|
|
739
747
|
def register_queue(queue)
|
740
748
|
@queues[queue.name] = queue
|
@@ -743,6 +751,10 @@ module Bunny
|
|
743
751
|
def find_queue(name)
|
744
752
|
@queues[name]
|
745
753
|
end
|
754
|
+
|
755
|
+
def deregister_exchange(exchange)
|
756
|
+
@exchanges.delete(exchange.name)
|
757
|
+
end
|
746
758
|
|
747
759
|
def register_exchange(exchange)
|
748
760
|
@exchanges[exchange.name] = exchange
|
data/lib/bunny/consumer.rb
CHANGED
@@ -14,7 +14,7 @@ module Bunny
|
|
14
14
|
|
15
15
|
|
16
16
|
|
17
|
-
def initialize(channel, queue, consumer_tag = channel.generate_consumer_tag, no_ack =
|
17
|
+
def initialize(channel, queue, consumer_tag = channel.generate_consumer_tag, no_ack = true, exclusive = false, arguments = {})
|
18
18
|
@channel = channel || raise(ArgumentError, "channel is nil")
|
19
19
|
@queue = queue || raise(ArgumentError, "queue is nil")
|
20
20
|
@consumer_tag = consumer_tag
|
data/lib/bunny/exchange.rb
CHANGED
data/lib/bunny/queue.rb
CHANGED
data/lib/bunny/session.rb
CHANGED
data/lib/bunny/version.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "A message" do
|
4
|
+
let(:connection) do
|
5
|
+
c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
|
6
|
+
c.start
|
7
|
+
c
|
8
|
+
end
|
9
|
+
|
10
|
+
after :all do
|
11
|
+
connection.close if connection.open?
|
12
|
+
end
|
13
|
+
|
14
|
+
it "is considered to be dead-lettered when it is rejected without requeueing" do
|
15
|
+
ch = connection.create_channel
|
16
|
+
x = ch.fanout("amq.fanout")
|
17
|
+
dlx = ch.fanout("bunny.tests.dlx.exchange")
|
18
|
+
q = ch.queue("", :exclusive => true, :arguments => {"x-dead-letter-exchange" => dlx.name}).bind(x)
|
19
|
+
# dead letter queue
|
20
|
+
dlq = ch.queue("", :exclusive => true).bind(dlx)
|
21
|
+
|
22
|
+
x.publish("")
|
23
|
+
sleep 0.2
|
24
|
+
|
25
|
+
delivery_info, _, _ = q.pop(:ack => true)
|
26
|
+
dlq.message_count.should be_zero
|
27
|
+
ch.nack(delivery_info.delivery_tag, false)
|
28
|
+
|
29
|
+
sleep 0.2
|
30
|
+
q.message_count.should be_zero
|
31
|
+
dlq.message_count.should == 1
|
32
|
+
|
33
|
+
dlx.delete
|
34
|
+
end
|
35
|
+
|
36
|
+
it "is considered to be dead-lettered when it expires" do
|
37
|
+
ch = connection.create_channel
|
38
|
+
x = ch.fanout("amq.fanout")
|
39
|
+
dlx = ch.fanout("bunny.tests.dlx.exchange")
|
40
|
+
q = ch.queue("", :exclusive => true, :arguments => {"x-dead-letter-exchange" => dlx.name, "x-message-ttl" => 100}).bind(x)
|
41
|
+
# dead letter queue
|
42
|
+
dlq = ch.queue("", :exclusive => true).bind(dlx)
|
43
|
+
|
44
|
+
x.publish("")
|
45
|
+
sleep 0.2
|
46
|
+
|
47
|
+
q.message_count.should be_zero
|
48
|
+
dlq.message_count.should == 1
|
49
|
+
|
50
|
+
dlx.delete
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Sender-selected distribution" do
|
4
|
+
let(:connection) do
|
5
|
+
c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
|
6
|
+
c.start
|
7
|
+
c
|
8
|
+
end
|
9
|
+
|
10
|
+
after :all do
|
11
|
+
connection.close if connection.open?
|
12
|
+
end
|
13
|
+
|
14
|
+
it "lets publishers specify additional routing keys using CC and BCC headers" do
|
15
|
+
ch = connection.create_channel
|
16
|
+
x = ch.direct("bunny.tests.ssd.exchange")
|
17
|
+
q1 = ch.queue("", :exclusive => true).bind(x, :routing_key => "one")
|
18
|
+
q2 = ch.queue("", :exclusive => true).bind(x, :routing_key => "two")
|
19
|
+
q3 = ch.queue("", :exclusive => true).bind(x, :routing_key => "three")
|
20
|
+
q4 = ch.queue("", :exclusive => true).bind(x, :routing_key => "four")
|
21
|
+
|
22
|
+
n = 10
|
23
|
+
n.times do |i|
|
24
|
+
x.publish("Message #{i}", :routing_key => "one", :headers => {"CC" => ["two", "three"]})
|
25
|
+
end
|
26
|
+
|
27
|
+
sleep 0.5
|
28
|
+
|
29
|
+
q1.message_count.should == n
|
30
|
+
q2.message_count.should == n
|
31
|
+
q3.message_count.should == n
|
32
|
+
q4.message_count.should be_zero
|
33
|
+
|
34
|
+
x.delete
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Bunny::Channel, "#open" do
|
4
|
+
let(:connection) do
|
5
|
+
c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
|
6
|
+
c.start
|
7
|
+
c
|
8
|
+
end
|
9
|
+
|
10
|
+
after :all do
|
11
|
+
connection.close if connection.open?
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
it "properly resets channel exception state" do
|
16
|
+
ch = connection.create_channel
|
17
|
+
|
18
|
+
begin
|
19
|
+
ch.queue("bunny.tests.does.not.exist", :passive => true)
|
20
|
+
rescue Bunny::NotFound
|
21
|
+
# expected
|
22
|
+
end
|
23
|
+
|
24
|
+
# reopen the channel
|
25
|
+
ch.open
|
26
|
+
|
27
|
+
# should not raise
|
28
|
+
q = ch.queue("bunny.tests.my.queue")
|
29
|
+
q.delete
|
30
|
+
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bunny
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.0.
|
4
|
+
version: 0.9.0.pre5
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2013-01-09 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: amq-protocol
|
@@ -60,6 +60,20 @@ files:
|
|
60
60
|
- bunny.gemspec
|
61
61
|
- examples/connection/heartbeat.rb
|
62
62
|
- examples/connection/unknown_host.rb
|
63
|
+
- examples/guides/exchanges/direct_exchange_routing.rb
|
64
|
+
- examples/guides/exchanges/fanout_exchange_routing.rb
|
65
|
+
- examples/guides/exchanges/headers_exchange_routing.rb
|
66
|
+
- examples/guides/exchanges/mandatory_messages.rb
|
67
|
+
- examples/guides/extensions/alternate_exchange.rb
|
68
|
+
- examples/guides/extensions/basic_nack.rb
|
69
|
+
- examples/guides/extensions/consumer_cancellation_notification.rb
|
70
|
+
- examples/guides/extensions/dead_letter_exchange.rb
|
71
|
+
- examples/guides/extensions/exchange_to_exchange_bindings.rb
|
72
|
+
- examples/guides/extensions/per_message_ttl.rb
|
73
|
+
- examples/guides/extensions/per_queue_message_ttl.rb
|
74
|
+
- examples/guides/extensions/publisher_confirms.rb
|
75
|
+
- examples/guides/extensions/queue_lease.rb
|
76
|
+
- examples/guides/extensions/sender_selected_distribution.rb
|
63
77
|
- examples/guides/getting_started/blabbr.rb
|
64
78
|
- examples/guides/getting_started/hello_world.rb
|
65
79
|
- examples/guides/getting_started/weathr.rb
|
@@ -107,6 +121,7 @@ files:
|
|
107
121
|
- spec/higher_level_api/integration/confirm_select_spec.rb
|
108
122
|
- spec/higher_level_api/integration/connection_spec.rb
|
109
123
|
- spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb
|
124
|
+
- spec/higher_level_api/integration/dead_lettering_spec.rb
|
110
125
|
- spec/higher_level_api/integration/exchange_bind_spec.rb
|
111
126
|
- spec/higher_level_api/integration/exchange_declare_spec.rb
|
112
127
|
- spec/higher_level_api/integration/exchange_delete_spec.rb
|
@@ -118,9 +133,11 @@ files:
|
|
118
133
|
- spec/higher_level_api/integration/queue_delete_spec.rb
|
119
134
|
- spec/higher_level_api/integration/queue_purge_spec.rb
|
120
135
|
- spec/higher_level_api/integration/queue_unbind_spec.rb
|
136
|
+
- spec/higher_level_api/integration/sender_selected_distribution_spec.rb
|
121
137
|
- spec/higher_level_api/integration/tx_commit_spec.rb
|
122
138
|
- spec/higher_level_api/integration/tx_rollback_spec.rb
|
123
139
|
- spec/issues/issue78_spec.rb
|
140
|
+
- spec/issues/issue83_spec.rb
|
124
141
|
- spec/lower_level_api/integration/basic_cancel_spec.rb
|
125
142
|
- spec/lower_level_api/integration/basic_consume_spec.rb
|
126
143
|
- spec/spec_helper.rb
|
@@ -172,6 +189,7 @@ test_files:
|
|
172
189
|
- spec/higher_level_api/integration/confirm_select_spec.rb
|
173
190
|
- spec/higher_level_api/integration/connection_spec.rb
|
174
191
|
- spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb
|
192
|
+
- spec/higher_level_api/integration/dead_lettering_spec.rb
|
175
193
|
- spec/higher_level_api/integration/exchange_bind_spec.rb
|
176
194
|
- spec/higher_level_api/integration/exchange_declare_spec.rb
|
177
195
|
- spec/higher_level_api/integration/exchange_delete_spec.rb
|
@@ -183,9 +201,11 @@ test_files:
|
|
183
201
|
- spec/higher_level_api/integration/queue_delete_spec.rb
|
184
202
|
- spec/higher_level_api/integration/queue_purge_spec.rb
|
185
203
|
- spec/higher_level_api/integration/queue_unbind_spec.rb
|
204
|
+
- spec/higher_level_api/integration/sender_selected_distribution_spec.rb
|
186
205
|
- spec/higher_level_api/integration/tx_commit_spec.rb
|
187
206
|
- spec/higher_level_api/integration/tx_rollback_spec.rb
|
188
207
|
- spec/issues/issue78_spec.rb
|
208
|
+
- spec/issues/issue83_spec.rb
|
189
209
|
- spec/lower_level_api/integration/basic_cancel_spec.rb
|
190
210
|
- spec/lower_level_api/integration/basic_consume_spec.rb
|
191
211
|
- spec/spec_helper.rb
|