bunny 1.0.0.pre3 → 1.0.0.pre4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -1
  3. data/ChangeLog.md +54 -0
  4. data/README.md +5 -5
  5. data/benchmarks/mutex_and_monitor.rb +42 -0
  6. data/bunny.gemspec +2 -2
  7. data/examples/guides/extensions/connection_blocked.rb +35 -0
  8. data/lib/bunny/channel.rb +16 -7
  9. data/lib/bunny/exceptions.rb +4 -1
  10. data/lib/bunny/reader_loop.rb +17 -3
  11. data/lib/bunny/session.rb +58 -6
  12. data/lib/bunny/transport.rb +10 -1
  13. data/lib/bunny/version.rb +1 -1
  14. data/spec/higher_level_api/integration/basic_cancel_spec.rb +1 -1
  15. data/spec/higher_level_api/integration/basic_consume_spec.rb +1 -1
  16. data/spec/higher_level_api/integration/basic_nack_spec.rb +1 -1
  17. data/spec/higher_level_api/integration/basic_publish_spec.rb +1 -1
  18. data/spec/higher_level_api/integration/basic_qos_spec.rb +5 -8
  19. data/spec/higher_level_api/integration/basic_reject_spec.rb +16 -17
  20. data/spec/higher_level_api/integration/basic_return_spec.rb +1 -1
  21. data/spec/higher_level_api/integration/channel_close_spec.rb +6 -10
  22. data/spec/higher_level_api/integration/channel_flow_spec.rb +6 -9
  23. data/spec/higher_level_api/integration/channel_open_spec.rb +11 -20
  24. data/spec/higher_level_api/integration/confirm_select_spec.rb +1 -1
  25. data/spec/higher_level_api/integration/connection_spec.rb +1 -1
  26. data/spec/higher_level_api/integration/connection_stop_spec.rb +13 -0
  27. data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +1 -1
  28. data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +46 -1
  29. data/spec/higher_level_api/integration/dead_lettering_spec.rb +1 -1
  30. data/spec/higher_level_api/integration/exchange_bind_spec.rb +1 -1
  31. data/spec/higher_level_api/integration/exchange_declare_spec.rb +1 -1
  32. data/spec/higher_level_api/integration/exchange_delete_spec.rb +1 -1
  33. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +1 -1
  34. data/spec/higher_level_api/integration/exclusive_queue_spec.rb +28 -0
  35. data/spec/higher_level_api/integration/merry_go_round_spec.rb +1 -1
  36. data/spec/higher_level_api/integration/message_properties_access_spec.rb +1 -1
  37. data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +1 -1
  38. data/spec/higher_level_api/integration/publisher_confirms_spec.rb +1 -1
  39. data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +1 -1
  40. data/spec/higher_level_api/integration/queue_declare_spec.rb +1 -1
  41. data/spec/higher_level_api/integration/queue_delete_spec.rb +2 -2
  42. data/spec/higher_level_api/integration/queue_purge_spec.rb +1 -1
  43. data/spec/higher_level_api/integration/queue_unbind_spec.rb +2 -2
  44. data/spec/higher_level_api/integration/read_only_consumer_spec.rb +1 -1
  45. data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +2 -2
  46. data/spec/higher_level_api/integration/tls_connection_spec.rb +2 -2
  47. data/spec/higher_level_api/integration/tx_commit_spec.rb +1 -1
  48. data/spec/higher_level_api/integration/tx_rollback_spec.rb +1 -1
  49. data/spec/stress/connection_open_close_spec.rb +25 -2
  50. data/spec/unit/concurrent/condition_spec.rb +53 -46
  51. data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +48 -9
  52. metadata +10 -5
@@ -7,7 +7,7 @@ describe Bunny::Exchange, "#delete" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Exchange do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe Bunny::Queue 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 :each do
11
+ connection.close if connection.open?
12
+ end
13
+
14
+ it "is closed when the connection it was declared on is closed" do
15
+ ch1 = connection.create_channel
16
+ ch2 = connection.create_channel
17
+ q = ch1.queue("", :exclusive => true)
18
+
19
+ ch1.queue_declare(q.name, :passive => true)
20
+ ch2.queue_declare(q.name, :passive => true)
21
+
22
+ ch1.close
23
+ ch2.queue_declare(q.name, :passive => true)
24
+
25
+ ch2.queue_delete(q.name)
26
+ ch2.close
27
+ end
28
+ end
@@ -31,7 +31,7 @@ describe "A message that is proxied by multiple intermediate consumers" do
31
31
  c
32
32
  end
33
33
 
34
- after :all do
34
+ after :each do
35
35
  [c1, c2, c3, c4, c5].each do |c|
36
36
  c.close if c.open?
37
37
  end
@@ -7,7 +7,7 @@ describe Bunny::Queue, "#subscribe" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe "amq.* exchanges" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe Bunny::Channel do
4
4
  let(:connection) do
5
- c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
5
+ c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed", :continuation_timeout => 10000)
6
6
  c.start
7
7
  c
8
8
  end
@@ -11,7 +11,7 @@ unless ENV["CI"]
11
11
  c
12
12
  end
13
13
 
14
- after :all do
14
+ after :each do
15
15
  connection.close if connection.open?
16
16
  end
17
17
 
@@ -7,7 +7,7 @@ describe Bunny::Queue do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Queue, "#delete" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
@@ -22,7 +22,7 @@ describe Bunny::Queue, "#delete" do
22
22
  expect {
23
23
  q.delete
24
24
  }.to raise_error(Bunny::NotFound)
25
-
25
+
26
26
  ch.queues.size.should == 0
27
27
  end
28
28
  end
@@ -7,7 +7,7 @@ describe Bunny::Queue do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Queue, "bound to an exchange" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
@@ -37,7 +37,7 @@ describe Bunny::Queue, "NOT bound to an exchange" do
37
37
  c
38
38
  end
39
39
 
40
- after :all do
40
+ after :each do
41
41
  connection.close
42
42
  end
43
43
 
@@ -13,7 +13,7 @@ describe Bunny::Queue, "#subscribe" do
13
13
  c
14
14
  end
15
15
 
16
- after :all do
16
+ after :each do
17
17
  publisher_connection.close if publisher_connection.open?
18
18
  consumer_connection.close if consumer_connection.open?
19
19
  end
@@ -7,7 +7,7 @@ describe "Sender-selected distribution" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -23,7 +23,7 @@ describe "Sender-selected distribution" do
23
23
  n.times do |i|
24
24
  x.publish("Message #{i}", :routing_key => "one", :headers => {"CC" => ["two", "three"]})
25
25
  end
26
-
26
+
27
27
  sleep 0.5
28
28
 
29
29
  q1.message_count.should == n
@@ -15,7 +15,7 @@ unless ENV["CI"]
15
15
  c
16
16
  end
17
17
 
18
- after :all do
18
+ after :each do
19
19
  connection.close
20
20
  end
21
21
 
@@ -57,7 +57,7 @@ unless ENV["CI"]
57
57
  c
58
58
  end
59
59
 
60
- after :all do
60
+ after :each do
61
61
  connection.close
62
62
  end
63
63
 
@@ -7,7 +7,7 @@ describe Bunny::Channel, "#tx_commit" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Channel, "#tx_rollback" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -1,8 +1,17 @@
1
1
  require "spec_helper"
2
2
 
3
- unless RUBY_ENGINE == "jruby"
3
+ unless RUBY_ENGINE == "jruby" && !ENV["FORCE_JRUBY_RUN"]
4
4
  describe Bunny::Session do
5
- 4000.times do |i|
5
+ # creating thousands of connections means creating
6
+ # twice as many threads and this won't fly with the JVM
7
+ # in CI containers. MK.
8
+ n = if RUBY_ENGINE == "jruby"
9
+ 250
10
+ else
11
+ 2500
12
+ end
13
+
14
+ n.times do |i|
6
15
  it "can be closed (take #{i})" do
7
16
  c = Bunny.new(:automatically_recover => false)
8
17
  c.start
@@ -13,5 +22,19 @@ unless RUBY_ENGINE == "jruby"
13
22
  c.should be_closed
14
23
  end
15
24
  end
25
+
26
+ context "in the single threaded mode" do
27
+ n.times do |i|
28
+ it "can be closed (take #{i})" do
29
+ c = Bunny.new(:automatically_recover => false, :threaded => false)
30
+ c.start
31
+ ch = c.create_channel
32
+
33
+ c.should be_connected
34
+ c.stop
35
+ c.should be_closed
36
+ end
37
+ end
38
+ end
16
39
  end
17
40
  end
@@ -2,73 +2,80 @@ require "spec_helper"
2
2
  require "bunny/concurrent/condition"
3
3
 
4
4
  describe Bunny::Concurrent::Condition do
5
+
5
6
  describe "#wait" do
6
- it "blocks current thread until notified" do
7
- condition = described_class.new
8
- xs = []
7
+ 100.times do |i|
8
+ it "blocks current thread until notified (take #{i})" do
9
+ condition = described_class.new
10
+ xs = []
9
11
 
10
- t = Thread.new do
11
- xs << :notified
12
+ t = Thread.new do
13
+ xs << :notified
12
14
 
13
- sleep 0.25
14
- condition.notify
15
- end
16
- t.abort_on_exception = true
15
+ sleep 0.25
16
+ condition.notify
17
+ end
18
+ t.abort_on_exception = true
17
19
 
18
- condition.wait
19
- xs.should == [:notified]
20
+ condition.wait
21
+ xs.should == [:notified]
22
+ end
20
23
  end
21
24
  end
22
25
 
23
26
  describe "#notify" do
24
- it "notifies a single thread waiting on the latch" do
25
- mutex = Mutex.new
26
- condition = described_class.new
27
- xs = []
27
+ 100.times do |i|
28
+ it "notifies a single thread waiting on the latch (take #{i})" do
29
+ mutex = Mutex.new
30
+ condition = described_class.new
31
+ xs = []
28
32
 
29
- t1 = Thread.new do
30
- condition.wait
31
- mutex.synchronize { xs << :notified1 }
32
- end
33
- t1.abort_on_exception = true
33
+ t1 = Thread.new do
34
+ condition.wait
35
+ mutex.synchronize { xs << :notified1 }
36
+ end
37
+ t1.abort_on_exception = true
34
38
 
35
- t2 = Thread.new do
36
- condition.wait
37
- mutex.synchronize { xs << :notified2 }
38
- end
39
- t2.abort_on_exception = true
39
+ t2 = Thread.new do
40
+ condition.wait
41
+ mutex.synchronize { xs << :notified2 }
42
+ end
43
+ t2.abort_on_exception = true
40
44
 
41
- sleep 0.25
42
- condition.notify
43
- sleep 0.5
44
- xs.should satisfy { |ys| ys.size == 1 && (ys.include?(:notified1) || ys.include?(:notified2)) }
45
+ sleep 0.25
46
+ condition.notify
47
+ sleep 0.5
48
+ xs.should satisfy { |ys| ys.size == 1 && (ys.include?(:notified1) || ys.include?(:notified2)) }
49
+ end
45
50
  end
46
51
  end
47
52
 
48
53
  describe "#notify_all" do
49
- let(:n) { 120 }
54
+ let(:n) { 30 }
50
55
 
51
- it "notifies all the threads waiting on the latch" do
52
- mutex = Mutex.new
53
- condition = described_class.new
54
- @xs = []
56
+ 100.times do |i|
57
+ it "notifies all the threads waiting on the latch (take #{i})" do
58
+ mutex = Mutex.new
59
+ condition = described_class.new
60
+ @xs = []
55
61
 
56
- n.times do |i|
57
- t = Thread.new do
58
- condition.wait
59
- mutex.synchronize { @xs << "notified#{i + 1}".to_sym }
62
+ n.times do |i|
63
+ t = Thread.new do
64
+ condition.wait
65
+ mutex.synchronize { @xs << "notified#{i + 1}".to_sym }
66
+ end
67
+ t.abort_on_exception = true
60
68
  end
61
- t.abort_on_exception = true
62
- end
63
69
 
64
- sleep 0.5
65
- condition.notify_all
66
- sleep 0.5
70
+ sleep 0.5
71
+ condition.notify_all
72
+ sleep 0.5
67
73
 
68
- n.times do |i|
69
- item = "notified#{i + 1}".to_sym
74
+ n.times do |i|
75
+ item = "notified#{i + 1}".to_sym
70
76
 
71
- @xs.should include(item)
77
+ @xs.should include(item)
78
+ end
72
79
  end
73
80
  end
74
81
  end
@@ -1,34 +1,73 @@
1
1
  require "spec_helper"
2
2
  require "bunny/concurrent/synchronized_sorted_set"
3
3
 
4
- describe Bunny::Concurrent::SynchronizedSortedSet do
5
- it "synchronizes common operations needed by Bunny" do
6
- s = described_class.new
7
- s.length.should == 0
4
+ unless ENV["CI"]
5
+ describe Bunny::Concurrent::SynchronizedSortedSet do
6
+ 50.times do |i|
7
+ it "provides the same API as SortedSet for key operations (take #{i})" do
8
+ s = described_class.new
9
+ s.length.should == 0
8
10
 
9
- 10.times do
10
- Thread.new do
11
11
  s << 1
12
+ s.length.should == 1
12
13
  s << 1
14
+ s.length.should == 1
13
15
  s << 2
16
+ s.length.should == 2
14
17
  s << 3
18
+ s.length.should == 3
15
19
  s << 4
20
+ s.length.should == 4
16
21
  s << 4
17
22
  s << 4
18
23
  s << 4
24
+ s.length.should == 4
19
25
  s << 5
26
+ s.length.should == 5
20
27
  s << 5
21
28
  s << 5
22
29
  s << 5
30
+ s.length.should == 5
23
31
  s << 6
32
+ s.length.should == 6
24
33
  s << 7
34
+ s.length.should == 7
25
35
  s << 8
36
+ s.length.should == 8
26
37
  s.delete 8
38
+ s.length.should == 7
27
39
  s.delete_if { |i| i == 1 }
40
+ s.length.should == 6
28
41
  end
29
- end
30
- sleep 2.0
42
+ it "synchronizes common operations needed by Bunny (take #{i})" do
43
+ s = described_class.new
44
+ s.length.should == 0
45
+
46
+ 10.times do
47
+ Thread.new do
48
+ s << 1
49
+ s << 1
50
+ s << 2
51
+ s << 3
52
+ s << 4
53
+ s << 4
54
+ s << 4
55
+ s << 4
56
+ s << 5
57
+ s << 5
58
+ s << 5
59
+ s << 5
60
+ s << 6
61
+ s << 7
62
+ s << 8
63
+ s.delete 8
64
+ s.delete_if { |i| i == 1 }
65
+ end
66
+ end
67
+ sleep 0.5
31
68
 
32
- s.length.should == 6
69
+ s.length.should == 6
70
+ end
71
+ end
33
72
  end
34
73
  end