bunny 0.9.0.pre7 → 0.9.0.pre8
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.md +22 -0
- data/Gemfile +2 -2
- data/README.md +2 -2
- data/examples/connection/disabled_automatic_recovery.rb +34 -0
- data/lib/bunny.rb +8 -0
- data/lib/bunny/channel.rb +16 -13
- data/lib/bunny/channel_id_allocator.rb +16 -13
- data/lib/bunny/exceptions.rb +45 -33
- data/lib/bunny/main_loop.rb +27 -12
- data/lib/bunny/queue.rb +1 -1
- data/lib/bunny/session.rb +54 -10
- data/lib/bunny/socket.rb +2 -2
- data/lib/bunny/ssl_socket.rb +33 -0
- data/lib/bunny/transport.rb +124 -40
- data/lib/bunny/version.rb +1 -1
- data/spec/higher_level_api/integration/basic_consume_spec.rb +39 -0
- data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +51 -0
- data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +3 -3
- data/spec/issues/issue100_spec.rb +40 -0
- data/spec/issues/issue97_spec.rb +13 -11
- data/spec/stress/channel_open_stress_spec.rb +49 -0
- data/spec/stress/concurrent_consumers_stress_spec.rb +66 -0
- data/spec/stress/concurrent_publishers_stress_spec.rb +58 -0
- data/spec/unit/concurrent/condition_spec.rb +5 -0
- metadata +14 -4
- data/spec/higher_level_api/integration/channel_open_stress_spec.rb +0 -22
data/spec/issues/issue97_spec.rb
CHANGED
@@ -15,21 +15,23 @@ describe "Message framing implementation" do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
unless ENV["CI"]
|
19
|
+
context "with payload ~ 248K in size including non-ASCII characters" do
|
20
|
+
it "successfully frames the message" do
|
21
|
+
ch = connection.create_channel
|
21
22
|
|
22
|
-
|
23
|
-
|
23
|
+
q = ch.queue("", :exclusive => true)
|
24
|
+
x = ch.default_exchange
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
body = IO.read("spec/issues/issue97_attachment.json")
|
27
|
+
x.publish(body, :routing_key => q.name, :persistent => true)
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
sleep(1)
|
30
|
+
q.message_count.should == 1
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
q.purge
|
33
|
+
ch.close
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Rapidly opening and closing lots of channels" do
|
4
|
+
let(:connection) do
|
5
|
+
c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed", :automatic_recovery => false)
|
6
|
+
c.start
|
7
|
+
c
|
8
|
+
end
|
9
|
+
|
10
|
+
after :all do
|
11
|
+
connection.close
|
12
|
+
end
|
13
|
+
|
14
|
+
context "in a single-threaded scenario" do
|
15
|
+
let(:n) { 500 }
|
16
|
+
|
17
|
+
it "works correctly" do
|
18
|
+
xs = Array.new(n) { connection.create_channel }
|
19
|
+
puts "Opened #{n} channels"
|
20
|
+
|
21
|
+
xs.size.should == n
|
22
|
+
xs.each do |ch|
|
23
|
+
ch.close
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "in a multi-threaded scenario" do
|
29
|
+
# actually, on MRI values greater than ~100 will eventually cause write
|
30
|
+
# operations to fail with a timeout (1 second is not enough)
|
31
|
+
# which will cause recovery to re-acquire @channel_mutex in Session.
|
32
|
+
# Because Ruby's mutexes are not re-entrant, it will raise a ThreadError.
|
33
|
+
#
|
34
|
+
# But this already demonstrates that within these platform constraints,
|
35
|
+
# Bunny is safe to use in such scenarios.
|
36
|
+
let(:n) { 50 }
|
37
|
+
|
38
|
+
it "works correctly" do
|
39
|
+
n.times do
|
40
|
+
t = Thread.new do
|
41
|
+
ch = connection.create_channel
|
42
|
+
|
43
|
+
ch.close
|
44
|
+
end
|
45
|
+
t.abort_on_exception = true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe "Concurrent consumers sharing a connection" do
|
5
|
+
let(:connection) do
|
6
|
+
c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed", :automatic_recovery => false)
|
7
|
+
c.start
|
8
|
+
c
|
9
|
+
end
|
10
|
+
|
11
|
+
after :all do
|
12
|
+
connection.close
|
13
|
+
end
|
14
|
+
|
15
|
+
def any_not_drained?(qs)
|
16
|
+
qs.any? { |q| !q.message_count.zero? }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when publishing thousands of messages over 128K in size" do
|
20
|
+
let(:colors) { ["red", "blue", "white"] }
|
21
|
+
|
22
|
+
let(:n) { 32 }
|
23
|
+
let(:m) { 1000 }
|
24
|
+
|
25
|
+
it "successfully drain all queues" do
|
26
|
+
ch = connection.create_channel
|
27
|
+
body = "абвг"
|
28
|
+
x = ch.topic("bunny.stress.concurrent.consumers.topic", :durable => true)
|
29
|
+
|
30
|
+
chs = {}
|
31
|
+
n.times do |i|
|
32
|
+
chs[i] = connection.create_channel
|
33
|
+
end
|
34
|
+
qs = []
|
35
|
+
|
36
|
+
n.times do |i|
|
37
|
+
t = Thread.new do
|
38
|
+
cht = chs[i]
|
39
|
+
|
40
|
+
q = cht.queue("", :exclusive => true)
|
41
|
+
q.bind(x.name, :routing_key => colors.sample).subscribe do |delivery_info, meta, payload|
|
42
|
+
# no-op
|
43
|
+
end
|
44
|
+
qs << q
|
45
|
+
end
|
46
|
+
t.abort_on_exception = true
|
47
|
+
end
|
48
|
+
|
49
|
+
sleep 1.0
|
50
|
+
|
51
|
+
5.times do |i|
|
52
|
+
m.times do
|
53
|
+
x.publish(body, :routing_key => colors.sample)
|
54
|
+
end
|
55
|
+
puts "Published #{(i + 1) * m} messages..."
|
56
|
+
end
|
57
|
+
|
58
|
+
while any_not_drained?(qs)
|
59
|
+
sleep 1.0
|
60
|
+
end
|
61
|
+
puts "Drained all the queues..."
|
62
|
+
|
63
|
+
ch.close
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe "Concurrent publishers sharing a connection" do
|
5
|
+
let(:connection) do
|
6
|
+
c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed", :automatically_recover => false)
|
7
|
+
c.start
|
8
|
+
c
|
9
|
+
end
|
10
|
+
|
11
|
+
after :all do
|
12
|
+
connection.close
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:n) { 32 }
|
16
|
+
let(:m) { 1000 }
|
17
|
+
|
18
|
+
it "successfully finish publishing" do
|
19
|
+
ch = connection.create_channel
|
20
|
+
|
21
|
+
q = ch.queue("", :exclusive => true)
|
22
|
+
body = "сообщение"
|
23
|
+
|
24
|
+
# let the queue name be sent back by RabbitMQ
|
25
|
+
sleep 0.25
|
26
|
+
|
27
|
+
chs = {}
|
28
|
+
n.times do |i|
|
29
|
+
chs[i] = connection.create_channel
|
30
|
+
end
|
31
|
+
|
32
|
+
ts = []
|
33
|
+
|
34
|
+
n.times do |i|
|
35
|
+
t = Thread.new do
|
36
|
+
cht = chs[i]
|
37
|
+
x = ch.default_exchange
|
38
|
+
|
39
|
+
5.times do |i|
|
40
|
+
m.times do
|
41
|
+
x.publish(body, :routing_key => q.name)
|
42
|
+
end
|
43
|
+
puts "Published #{(i + 1) * m} messages..."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
t.abort_on_exception = true
|
47
|
+
|
48
|
+
ts << t
|
49
|
+
end
|
50
|
+
|
51
|
+
ts.each do |t|
|
52
|
+
t.join
|
53
|
+
end
|
54
|
+
|
55
|
+
sleep 4.0
|
56
|
+
q.message_count.should == 5 * n * m
|
57
|
+
end
|
58
|
+
end
|
@@ -13,6 +13,7 @@ describe Bunny::Concurrent::Condition do
|
|
13
13
|
sleep 0.25
|
14
14
|
condition.notify
|
15
15
|
end
|
16
|
+
t.abort_on_exception = true
|
16
17
|
|
17
18
|
condition.wait
|
18
19
|
xs.should == [:notified]
|
@@ -28,11 +29,13 @@ describe Bunny::Concurrent::Condition do
|
|
28
29
|
condition.wait
|
29
30
|
xs << :notified1
|
30
31
|
end
|
32
|
+
t1.abort_on_exception = true
|
31
33
|
|
32
34
|
t2 = Thread.new do
|
33
35
|
condition.wait
|
34
36
|
xs << :notified2
|
35
37
|
end
|
38
|
+
t2.abort_on_exception = true
|
36
39
|
|
37
40
|
sleep 0.25
|
38
41
|
condition.notify
|
@@ -50,11 +53,13 @@ describe Bunny::Concurrent::Condition do
|
|
50
53
|
condition.wait
|
51
54
|
@xs << :notified1
|
52
55
|
end
|
56
|
+
t1.abort_on_exception = true
|
53
57
|
|
54
58
|
t2 = Thread.new do
|
55
59
|
condition.wait
|
56
60
|
@xs << :notified2
|
57
61
|
end
|
62
|
+
t2.abort_on_exception = true
|
58
63
|
|
59
64
|
sleep 0.5
|
60
65
|
condition.notify_all
|
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.pre8
|
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: 2013-
|
16
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: amq-protocol
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- examples/connection/automatic_recovery_with_multiple_consumers.rb
|
65
65
|
- examples/connection/automatic_recovery_with_server_named_queues.rb
|
66
66
|
- examples/connection/channel_level_exception.rb
|
67
|
+
- examples/connection/disabled_automatic_recovery.rb
|
67
68
|
- examples/connection/heartbeat.rb
|
68
69
|
- examples/connection/unknown_host.rb
|
69
70
|
- examples/guides/exchanges/direct_exchange_routing.rb
|
@@ -106,6 +107,7 @@ files:
|
|
106
107
|
- lib/bunny/return_info.rb
|
107
108
|
- lib/bunny/session.rb
|
108
109
|
- lib/bunny/socket.rb
|
110
|
+
- lib/bunny/ssl_socket.rb
|
109
111
|
- lib/bunny/system_timer.rb
|
110
112
|
- lib/bunny/transport.rb
|
111
113
|
- lib/bunny/version.rb
|
@@ -123,9 +125,9 @@ files:
|
|
123
125
|
- spec/higher_level_api/integration/channel_close_spec.rb
|
124
126
|
- spec/higher_level_api/integration/channel_flow_spec.rb
|
125
127
|
- spec/higher_level_api/integration/channel_open_spec.rb
|
126
|
-
- spec/higher_level_api/integration/channel_open_stress_spec.rb
|
127
128
|
- spec/higher_level_api/integration/confirm_select_spec.rb
|
128
129
|
- spec/higher_level_api/integration/connection_spec.rb
|
130
|
+
- spec/higher_level_api/integration/consistent_hash_exchange_spec.rb
|
129
131
|
- spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb
|
130
132
|
- spec/higher_level_api/integration/dead_lettering_spec.rb
|
131
133
|
- spec/higher_level_api/integration/exchange_bind_spec.rb
|
@@ -144,6 +146,7 @@ files:
|
|
144
146
|
- spec/higher_level_api/integration/sender_selected_distribution_spec.rb
|
145
147
|
- spec/higher_level_api/integration/tx_commit_spec.rb
|
146
148
|
- spec/higher_level_api/integration/tx_rollback_spec.rb
|
149
|
+
- spec/issues/issue100_spec.rb
|
147
150
|
- spec/issues/issue78_spec.rb
|
148
151
|
- spec/issues/issue83_spec.rb
|
149
152
|
- spec/issues/issue97_attachment.json
|
@@ -151,6 +154,9 @@ files:
|
|
151
154
|
- spec/lower_level_api/integration/basic_cancel_spec.rb
|
152
155
|
- spec/lower_level_api/integration/basic_consume_spec.rb
|
153
156
|
- spec/spec_helper.rb
|
157
|
+
- spec/stress/channel_open_stress_spec.rb
|
158
|
+
- spec/stress/concurrent_consumers_stress_spec.rb
|
159
|
+
- spec/stress/concurrent_publishers_stress_spec.rb
|
154
160
|
- spec/unit/bunny_spec.rb
|
155
161
|
- spec/unit/concurrent/condition_spec.rb
|
156
162
|
- spec/unit/transport_spec.rb
|
@@ -196,9 +202,9 @@ test_files:
|
|
196
202
|
- spec/higher_level_api/integration/channel_close_spec.rb
|
197
203
|
- spec/higher_level_api/integration/channel_flow_spec.rb
|
198
204
|
- spec/higher_level_api/integration/channel_open_spec.rb
|
199
|
-
- spec/higher_level_api/integration/channel_open_stress_spec.rb
|
200
205
|
- spec/higher_level_api/integration/confirm_select_spec.rb
|
201
206
|
- spec/higher_level_api/integration/connection_spec.rb
|
207
|
+
- spec/higher_level_api/integration/consistent_hash_exchange_spec.rb
|
202
208
|
- spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb
|
203
209
|
- spec/higher_level_api/integration/dead_lettering_spec.rb
|
204
210
|
- spec/higher_level_api/integration/exchange_bind_spec.rb
|
@@ -217,6 +223,7 @@ test_files:
|
|
217
223
|
- spec/higher_level_api/integration/sender_selected_distribution_spec.rb
|
218
224
|
- spec/higher_level_api/integration/tx_commit_spec.rb
|
219
225
|
- spec/higher_level_api/integration/tx_rollback_spec.rb
|
226
|
+
- spec/issues/issue100_spec.rb
|
220
227
|
- spec/issues/issue78_spec.rb
|
221
228
|
- spec/issues/issue83_spec.rb
|
222
229
|
- spec/issues/issue97_attachment.json
|
@@ -224,6 +231,9 @@ test_files:
|
|
224
231
|
- spec/lower_level_api/integration/basic_cancel_spec.rb
|
225
232
|
- spec/lower_level_api/integration/basic_consume_spec.rb
|
226
233
|
- spec/spec_helper.rb
|
234
|
+
- spec/stress/channel_open_stress_spec.rb
|
235
|
+
- spec/stress/concurrent_consumers_stress_spec.rb
|
236
|
+
- spec/stress/concurrent_publishers_stress_spec.rb
|
227
237
|
- spec/unit/bunny_spec.rb
|
228
238
|
- spec/unit/concurrent/condition_spec.rb
|
229
239
|
- spec/unit/transport_spec.rb
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe "Rapidly opening and closing lots of channels" 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
|
12
|
-
end
|
13
|
-
|
14
|
-
it "works correctly" do
|
15
|
-
xs = Array.new(2000) { connection.create_channel }
|
16
|
-
|
17
|
-
xs.size.should == 2000
|
18
|
-
xs.each do |ch|
|
19
|
-
ch.close
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|