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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -1
- data/ChangeLog.md +54 -0
- data/README.md +5 -5
- data/benchmarks/mutex_and_monitor.rb +42 -0
- data/bunny.gemspec +2 -2
- data/examples/guides/extensions/connection_blocked.rb +35 -0
- data/lib/bunny/channel.rb +16 -7
- data/lib/bunny/exceptions.rb +4 -1
- data/lib/bunny/reader_loop.rb +17 -3
- data/lib/bunny/session.rb +58 -6
- data/lib/bunny/transport.rb +10 -1
- data/lib/bunny/version.rb +1 -1
- data/spec/higher_level_api/integration/basic_cancel_spec.rb +1 -1
- data/spec/higher_level_api/integration/basic_consume_spec.rb +1 -1
- data/spec/higher_level_api/integration/basic_nack_spec.rb +1 -1
- data/spec/higher_level_api/integration/basic_publish_spec.rb +1 -1
- data/spec/higher_level_api/integration/basic_qos_spec.rb +5 -8
- data/spec/higher_level_api/integration/basic_reject_spec.rb +16 -17
- data/spec/higher_level_api/integration/basic_return_spec.rb +1 -1
- data/spec/higher_level_api/integration/channel_close_spec.rb +6 -10
- data/spec/higher_level_api/integration/channel_flow_spec.rb +6 -9
- data/spec/higher_level_api/integration/channel_open_spec.rb +11 -20
- data/spec/higher_level_api/integration/confirm_select_spec.rb +1 -1
- data/spec/higher_level_api/integration/connection_spec.rb +1 -1
- data/spec/higher_level_api/integration/connection_stop_spec.rb +13 -0
- data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +1 -1
- data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +46 -1
- data/spec/higher_level_api/integration/dead_lettering_spec.rb +1 -1
- data/spec/higher_level_api/integration/exchange_bind_spec.rb +1 -1
- data/spec/higher_level_api/integration/exchange_declare_spec.rb +1 -1
- data/spec/higher_level_api/integration/exchange_delete_spec.rb +1 -1
- data/spec/higher_level_api/integration/exchange_unbind_spec.rb +1 -1
- data/spec/higher_level_api/integration/exclusive_queue_spec.rb +28 -0
- data/spec/higher_level_api/integration/merry_go_round_spec.rb +1 -1
- data/spec/higher_level_api/integration/message_properties_access_spec.rb +1 -1
- data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +1 -1
- data/spec/higher_level_api/integration/publisher_confirms_spec.rb +1 -1
- data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +1 -1
- data/spec/higher_level_api/integration/queue_declare_spec.rb +1 -1
- data/spec/higher_level_api/integration/queue_delete_spec.rb +2 -2
- data/spec/higher_level_api/integration/queue_purge_spec.rb +1 -1
- data/spec/higher_level_api/integration/queue_unbind_spec.rb +2 -2
- data/spec/higher_level_api/integration/read_only_consumer_spec.rb +1 -1
- data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +2 -2
- data/spec/higher_level_api/integration/tls_connection_spec.rb +2 -2
- data/spec/higher_level_api/integration/tx_commit_spec.rb +1 -1
- data/spec/higher_level_api/integration/tx_rollback_spec.rb +1 -1
- data/spec/stress/connection_open_close_spec.rb +25 -2
- data/spec/unit/concurrent/condition_spec.rb +53 -46
- data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +48 -9
- metadata +10 -5
@@ -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
|
@@ -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
|
@@ -7,7 +7,7 @@ describe Bunny::Queue, "#delete" do
|
|
7
7
|
c
|
8
8
|
end
|
9
9
|
|
10
|
-
after :
|
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, "bound to an exchange" do
|
|
7
7
|
c
|
8
8
|
end
|
9
9
|
|
10
|
-
after :
|
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 :
|
40
|
+
after :each do
|
41
41
|
connection.close
|
42
42
|
end
|
43
43
|
|
@@ -7,7 +7,7 @@ describe "Sender-selected distribution" do
|
|
7
7
|
c
|
8
8
|
end
|
9
9
|
|
10
|
-
after :
|
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
|
@@ -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
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
11
|
-
|
12
|
+
t = Thread.new do
|
13
|
+
xs << :notified
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
sleep 0.25
|
16
|
+
condition.notify
|
17
|
+
end
|
18
|
+
t.abort_on_exception = true
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
condition.wait
|
21
|
+
xs.should == [:notified]
|
22
|
+
end
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
23
26
|
describe "#notify" do
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
t1 = Thread.new do
|
34
|
+
condition.wait
|
35
|
+
mutex.synchronize { xs << :notified1 }
|
36
|
+
end
|
37
|
+
t1.abort_on_exception = true
|
34
38
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
t2 = Thread.new do
|
40
|
+
condition.wait
|
41
|
+
mutex.synchronize { xs << :notified2 }
|
42
|
+
end
|
43
|
+
t2.abort_on_exception = true
|
40
44
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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) {
|
54
|
+
let(:n) { 30 }
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
65
|
-
|
66
|
-
|
70
|
+
sleep 0.5
|
71
|
+
condition.notify_all
|
72
|
+
sleep 0.5
|
67
73
|
|
68
|
-
|
69
|
-
|
74
|
+
n.times do |i|
|
75
|
+
item = "notified#{i + 1}".to_sym
|
70
76
|
|
71
|
-
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
30
|
-
|
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
|
-
|
69
|
+
s.length.should == 6
|
70
|
+
end
|
71
|
+
end
|
33
72
|
end
|
34
73
|
end
|