bunny 1.1.0.rc1 → 1.1.0
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.
- checksums.yaml +4 -4
- data/ChangeLog.md +18 -0
- data/lib/bunny/channel.rb +1 -1
- data/lib/bunny/session.rb +30 -15
- data/lib/bunny/version.rb +1 -1
- data/spec/stress/channel_open_stress_spec.rb +50 -23
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 792b20042a60213fee5730fc4bf771dfe034d6bd
|
4
|
+
data.tar.gz: bd74266e1abd735322c449565e7d4041b3a51e09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92377d74df1988a233dd3f7f296dd5b9b3b328f38138e7e8b64afc1a0a42e1883945e0f64859ad7309bbf1b30a764ac8025be38cf90b0af93b73306f04baceea
|
7
|
+
data.tar.gz: ca8e3dd099586e3f784b7db55c6a2f8de8c68b279bb0d75ea5f6456e37161c05bab2e613c4120966c5ee98d468e1a07ab387e6fdc281d4e1435478a931c4cf9f
|
data/ChangeLog.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
## Changes between Bunny 1.1.0.rc1 and 1.1.0.rc2
|
2
|
+
|
3
|
+
### Synchronized Session#create_channel and Session#close_channel
|
4
|
+
|
5
|
+
Full bodies of `Bunny::Session#create_channel` and `Bunny::Session#close_channel`
|
6
|
+
are now synchronized, which makes sure concurrent `channel.open` and subsequent
|
7
|
+
operations (e.g. `exchange.declare`) do not result in connection-level exceptions
|
8
|
+
(incorrect connection state transitions).
|
9
|
+
|
10
|
+
### Corrected Recovery Log Message
|
11
|
+
|
12
|
+
Bunny will now use actual recovery interval in the log.
|
13
|
+
|
14
|
+
Contributed by Chad Fowler.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
1
19
|
## Changes between Bunny 1.1.0.pre2 and 1.1.0.rc1
|
2
20
|
|
3
21
|
### Full Channel State Recovery
|
data/lib/bunny/channel.rb
CHANGED
data/lib/bunny/session.rb
CHANGED
@@ -275,12 +275,14 @@ module Bunny
|
|
275
275
|
def create_channel(n = nil, consumer_pool_size = 1)
|
276
276
|
raise ArgumentError, "channel number 0 is reserved in the protocol and cannot be used" if 0 == n
|
277
277
|
|
278
|
-
|
279
|
-
ch
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
278
|
+
@channel_mutex.synchronize do
|
279
|
+
if n && (ch = @channels[n])
|
280
|
+
ch
|
281
|
+
else
|
282
|
+
ch = Bunny::Channel.new(self, n, ConsumerWorkPool.new(consumer_pool_size || 1))
|
283
|
+
ch.open
|
284
|
+
ch
|
285
|
+
end
|
284
286
|
end
|
285
287
|
end
|
286
288
|
alias channel create_channel
|
@@ -470,14 +472,16 @@ module Bunny
|
|
470
472
|
|
471
473
|
# @private
|
472
474
|
def close_channel(ch)
|
473
|
-
|
475
|
+
@channel_mutex.synchronize do
|
476
|
+
n = ch.number
|
474
477
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
+
@transport.send_frame(AMQ::Protocol::Channel::Close.encode(n, 200, "Goodbye", 0, 0))
|
479
|
+
@last_channel_close_ok = wait_on_continuations
|
480
|
+
raise_if_continuation_resulted_in_a_connection_error!
|
478
481
|
|
479
|
-
|
480
|
-
|
482
|
+
self.unregister_channel(ch)
|
483
|
+
@last_channel_close_ok
|
484
|
+
end
|
481
485
|
end
|
482
486
|
|
483
487
|
# @private
|
@@ -636,7 +640,7 @@ module Bunny
|
|
636
640
|
recover_channels
|
637
641
|
end
|
638
642
|
rescue TCPConnectionFailed, AMQ::Protocol::EmptyResponseError => e
|
639
|
-
@logger.warn "TCP connection failed, reconnecting in
|
643
|
+
@logger.warn "TCP connection failed, reconnecting in #{@network_recovery_interval} seconds"
|
640
644
|
sleep @network_recovery_interval
|
641
645
|
retry if recoverable_network_failure?(e)
|
642
646
|
end
|
@@ -807,6 +811,9 @@ module Bunny
|
|
807
811
|
# @private
|
808
812
|
def send_frame(frame, signal_activity = true)
|
809
813
|
if open?
|
814
|
+
# @transport_mutex.synchronize do
|
815
|
+
# @transport.write(frame.encode)
|
816
|
+
# end
|
810
817
|
@transport.write(frame.encode)
|
811
818
|
signal_activity! if signal_activity
|
812
819
|
else
|
@@ -904,7 +911,11 @@ module Bunny
|
|
904
911
|
@logger.debug "Sent connection.start-ok"
|
905
912
|
|
906
913
|
frame = begin
|
907
|
-
@transport.read_next_frame
|
914
|
+
fr = @transport.read_next_frame
|
915
|
+
while fr.is_a?(AMQ::Protocol::HeartbeatFrame)
|
916
|
+
fr = @transport.read_next_frame
|
917
|
+
end
|
918
|
+
fr
|
908
919
|
# frame timeout means the broker has closed the TCP connection, which it
|
909
920
|
# does per 0.9.1 spec.
|
910
921
|
rescue Errno::ECONNRESET, ClientTimeout, AMQ::Protocol::EmptyResponseError, EOFError, IOError => e
|
@@ -946,7 +957,11 @@ module Bunny
|
|
946
957
|
@logger.debug "Sent connection.open with vhost = #{self.vhost}"
|
947
958
|
|
948
959
|
frame2 = begin
|
949
|
-
@transport.read_next_frame
|
960
|
+
fr = @transport.read_next_frame
|
961
|
+
while fr.is_a?(AMQ::Protocol::HeartbeatFrame)
|
962
|
+
fr = @transport.read_next_frame
|
963
|
+
end
|
964
|
+
fr
|
950
965
|
# frame timeout means the broker has closed the TCP connection, which it
|
951
966
|
# does per 0.9.1 spec.
|
952
967
|
rescue Errno::ECONNRESET, ClientTimeout, AMQ::Protocol::EmptyResponseError, EOFError => e
|
data/lib/bunny/version.rb
CHANGED
@@ -1,32 +1,26 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
c.start
|
8
|
-
c
|
9
|
-
end
|
10
|
-
|
11
|
-
after :all do
|
12
|
-
connection.close
|
13
|
-
end
|
3
|
+
describe "Rapidly opening and closing lots of channels" do
|
4
|
+
connection = Bunny.new(:automatic_recovery => false).tap do |c|
|
5
|
+
c.start
|
6
|
+
end
|
14
7
|
|
15
|
-
|
16
|
-
|
8
|
+
context "in a single-threaded scenario" do
|
9
|
+
let(:n) { 500 }
|
17
10
|
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
it "works correctly" do
|
12
|
+
xs = Array.new(n) { connection.create_channel }
|
13
|
+
puts "Opened #{n} channels"
|
21
14
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
15
|
+
xs.size.should == n
|
16
|
+
xs.each do |ch|
|
17
|
+
ch.close
|
26
18
|
end
|
27
19
|
end
|
20
|
+
end
|
28
21
|
|
29
|
-
|
22
|
+
100.times do |i|
|
23
|
+
context "in a multi-threaded scenario A (take #{i})" do
|
30
24
|
# actually, on MRI values greater than ~100 will eventually cause write
|
31
25
|
# operations to fail with a timeout (1 second is not enough)
|
32
26
|
# which will cause recovery to re-acquire @channel_mutex in Session.
|
@@ -37,14 +31,47 @@ unless ENV["CI"]
|
|
37
31
|
let(:n) { 20 }
|
38
32
|
|
39
33
|
it "works correctly" do
|
34
|
+
ts = []
|
35
|
+
|
40
36
|
n.times do
|
41
37
|
t = Thread.new do
|
42
|
-
|
38
|
+
ch1 = connection.create_channel
|
39
|
+
q = ch1.queue("", :exclusive => true)
|
40
|
+
q.delete
|
41
|
+
ch1.close
|
43
42
|
|
44
|
-
|
43
|
+
ch2 = connection.create_channel
|
44
|
+
ch2.close
|
45
45
|
end
|
46
46
|
t.abort_on_exception = true
|
47
|
+
ts << t
|
47
48
|
end
|
49
|
+
|
50
|
+
ts.each { |t| t.join }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
100.times do |i|
|
56
|
+
context "in a multi-threaded scenario B (take #{i})" do
|
57
|
+
let(:n) { 20 }
|
58
|
+
|
59
|
+
it "works correctly" do
|
60
|
+
ts = []
|
61
|
+
|
62
|
+
n.times do
|
63
|
+
t = Thread.new do
|
64
|
+
3.times do
|
65
|
+
ch = connection.create_channel
|
66
|
+
x = ch.topic('bunny.stress.topics.t2', :durable => false)
|
67
|
+
ch.close
|
68
|
+
end
|
69
|
+
end
|
70
|
+
t.abort_on_exception = true
|
71
|
+
ts << t
|
72
|
+
end
|
73
|
+
|
74
|
+
ts.each { |t| t.join }
|
48
75
|
end
|
49
76
|
end
|
50
77
|
end
|
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: 1.1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Duncan
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-01-
|
15
|
+
date: 2014-01-12 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: amq-protocol
|
@@ -221,9 +221,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
221
221
|
version: '0'
|
222
222
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
223
|
requirements:
|
224
|
-
- - '
|
224
|
+
- - '>='
|
225
225
|
- !ruby/object:Gem::Version
|
226
|
-
version:
|
226
|
+
version: '0'
|
227
227
|
requirements: []
|
228
228
|
rubyforge_project:
|
229
229
|
rubygems_version: 2.1.11
|