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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 73298a109694af83bb99bf84847d60df16207fcf
4
- data.tar.gz: 7b5f3f2aa6f0f790fb9384e1ba08924e6ba60063
3
+ metadata.gz: 792b20042a60213fee5730fc4bf771dfe034d6bd
4
+ data.tar.gz: bd74266e1abd735322c449565e7d4041b3a51e09
5
5
  SHA512:
6
- metadata.gz: bede6aee3aa9976eeb91f016bc7214b90756d96b105e3a81c3214e0497a0500f3c5738af97a0674e028bacbcf9c7cde779dcd8ab4afefef2ba59ad539044885c
7
- data.tar.gz: cbcacfc53117c4a3a68e78ce0d3a6c4c817c81780cf2a3f0b5f0ed613a56ed5784d743521e0e535a447612522433136de3950720c8846bbbf2cb54b72a0e1223
6
+ metadata.gz: 92377d74df1988a233dd3f7f296dd5b9b3b328f38138e7e8b64afc1a0a42e1883945e0f64859ad7309bbf1b30a764ac8025be38cf90b0af93b73306f04baceea
7
+ data.tar.gz: ca8e3dd099586e3f784b7db55c6a2f8de8c68b279bb0d75ea5f6456e37161c05bab2e613c4120966c5ee98d468e1a07ab387e6fdc281d4e1435478a931c4cf9f
@@ -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
@@ -1422,7 +1422,7 @@ module Bunny
1422
1422
  release_all_continuations
1423
1423
 
1424
1424
  recover_prefetch_setting
1425
- recover_confirm_flag
1425
+ recover_confirm_mode
1426
1426
  recover_tx_mode
1427
1427
  recover_exchanges
1428
1428
  # this includes recovering bindings
@@ -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
- if n && (ch = @channels[n])
279
- ch
280
- else
281
- ch = Bunny::Channel.new(self, n, ConsumerWorkPool.new(consumer_pool_size || 1))
282
- ch.open
283
- ch
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
- n = ch.number
475
+ @channel_mutex.synchronize do
476
+ n = ch.number
474
477
 
475
- @transport.send_frame(AMQ::Protocol::Channel::Close.encode(n, 200, "Goodbye", 0, 0))
476
- @last_channel_close_ok = wait_on_continuations
477
- raise_if_continuation_resulted_in_a_connection_error!
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
- self.unregister_channel(ch)
480
- @last_channel_close_ok
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 5 seconds"
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
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Bunny
4
4
  # @return [String] Version of the library
5
- VERSION = "1.1.0.rc1"
5
+ VERSION = "1.1.0"
6
6
  end
@@ -1,32 +1,26 @@
1
1
  require "spec_helper"
2
2
 
3
- unless ENV["CI"]
4
- describe "Rapidly opening and closing lots of channels" 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
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
- context "in a single-threaded scenario" do
16
- let(:n) { 500 }
8
+ context "in a single-threaded scenario" do
9
+ let(:n) { 500 }
17
10
 
18
- it "works correctly" do
19
- xs = Array.new(n) { connection.create_channel }
20
- puts "Opened #{n} channels"
11
+ it "works correctly" do
12
+ xs = Array.new(n) { connection.create_channel }
13
+ puts "Opened #{n} channels"
21
14
 
22
- xs.size.should == n
23
- xs.each do |ch|
24
- ch.close
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
- context "in a multi-threaded scenario" do
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
- ch = connection.create_channel
38
+ ch1 = connection.create_channel
39
+ q = ch1.queue("", :exclusive => true)
40
+ q.delete
41
+ ch1.close
43
42
 
44
- ch.close
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.rc1
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-04 00:00:00.000000000 Z
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: 1.3.1
226
+ version: '0'
227
227
  requirements: []
228
228
  rubyforge_project:
229
229
  rubygems_version: 2.1.11