bunny 0.9.0.pre4 → 0.9.0.pre5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|