bunny 1.0.0.pre3 → 1.0.0.pre4

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