bunny 0.9.0.pre7 → 0.9.0.pre8
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.
- 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
|