bunny 1.0.4 → 1.0.5

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: 65bba4f160af1169e1e2d7f1e15045dad3fafb21
4
- data.tar.gz: 38db4dd54e20cd407012b4e81da4a537585fe7db
3
+ metadata.gz: c8837b72e1a3b2ce162fc168eb298bcc9089f1d1
4
+ data.tar.gz: 22a780ffdeff22a180470071ab8c90da2ef0ed81
5
5
  SHA512:
6
- metadata.gz: 180fcfdee5da277fb7d4e7d1249cfd0dda89f62539f3da1c669591468fc1b3a93d69e66334756aa151187ee799401b57648a04e99f0addaafc06f3409f7ac6ad
7
- data.tar.gz: 56906a33ce0109360cb65cfce44aed78bb0ae7c100369e4bda8f7531aa4153ba69fda011b8d4b699718b5590ab8460f46ae5355ee4fec5cb33f6c5ef63771d5c
6
+ metadata.gz: 35bb0e4f3cc1dbd35d1fe9e135059b695f2fde65f188265a685d35c11ecad0460409215235ff3b108474e0a6304cca1f00a43d477ca129f4c1f3ea0d50615e33
7
+ data.tar.gz: aa3ee730eb9f096e0f9268e3187741752f80877a5bea078039133ae830a83e177c435120f369953b122bb8c6bdb7250cf81a167675f1b6d8e22b1e74c9e0b466
@@ -1,3 +1,47 @@
1
+ ## Changes between Bunny 1.0.4 and 1.0.5
2
+
3
+ ### Single Threaded Mode Fixes
4
+
5
+ Single threaded mode no longer fails with
6
+
7
+ ```
8
+ undefined method `event_loop'
9
+ ```
10
+
11
+ ### connection.tune.channel_max No Longer Overflows
12
+
13
+ `connection.tune.channel_max` could previously be configured to values
14
+ greater than 2^16 - 1 (65535). This would result in a silent overflow
15
+ during serialization. The issue was harmless in practice but is still
16
+ a bug that can be quite confusing.
17
+
18
+ Bunny now caps max number of channels to 65535. This allows it to be
19
+ forward compatible with future RabbitMQ versions that may allow limiting
20
+ total # of open channels via server configuration.
21
+
22
+ ### Thread Leaks Fixes
23
+
24
+ Bunny will now correctly release heartbeat sender when allocating
25
+ a new one (usually happens only when connection recovers from a network
26
+ failure).
27
+
28
+ ### amq-protocol Update
29
+
30
+ Minimum `amq-protocol` version is now `1.9.0` which includes
31
+ bug fixes and performance improvements for channel ID allocator.
32
+
33
+
34
+
35
+ ## Changes between Bunny 1.0.3 and 1.0.4
36
+
37
+ ### Versioned Delivery Tag Fix
38
+
39
+ Versioned delivery tag now ensures all the arguments it operates
40
+ (original delivery tag, atomic fixnum instances, etc) are coerced to `Integer`
41
+ before comparison.
42
+
43
+ GitHub issues: #171.
44
+
1
45
  ## Changes between Bunny 1.0.2 and 1.0.3
2
46
 
3
47
  ### Eliminated Errouneous Debug Statement
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
29
29
  map { |mail| Base64.decode64(mail) }
30
30
 
31
31
  # Dependencies
32
- s.add_dependency "amq-protocol", ">= 1.8.0"
32
+ s.add_dependency "amq-protocol", ">= 1.9.0"
33
33
 
34
34
  # Files.
35
35
  s.has_rdoc = true
@@ -1681,7 +1681,7 @@ module Bunny
1681
1681
  @threads_waiting_on_basic_get_continuations.delete(t)
1682
1682
  end
1683
1683
  else
1684
- connection.event_loop.run_once until @basic_get_continuations.length > 0
1684
+ connection.reader_loop.run_once until @basic_get_continuations.length > 0
1685
1685
 
1686
1686
  @basic_get_continuations.pop
1687
1687
  end
@@ -1699,7 +1699,7 @@ module Bunny
1699
1699
  @threads_waiting_on_confirms_continuations.delete(t)
1700
1700
  end
1701
1701
  else
1702
- connection.event_loop.run_once until @confirms_continuations.length > 0
1702
+ connection.reader_loop.run_once until @confirms_continuations.length > 0
1703
1703
 
1704
1704
  @confirms_continuations.pop
1705
1705
  end
@@ -42,6 +42,18 @@ module Bunny
42
42
  end
43
43
  end
44
44
 
45
+ # Can indicate either a channel or connection-level issue
46
+ class NotAllowedError < Exception
47
+ attr_reader :connection, :connection_close
48
+
49
+ def initialize(message, connection, connection_close = nil)
50
+ super(message)
51
+
52
+ @connection = connection
53
+ @connection_close = connection_close
54
+ end
55
+ end
56
+
45
57
 
46
58
  # Raised when TCP connection to RabbitMQ fails because of an unresolved
47
59
  # hostname, connectivity problem, etc
@@ -36,6 +36,10 @@ module Bunny
36
36
  DEFAULT_HEARTBEAT = :server
37
37
  # @private
38
38
  DEFAULT_FRAME_MAX = 131072
39
+ # 2^16 - 1, maximum representable signed 16 bit integer.
40
+ # @private
41
+ CHANNEL_MAX_LIMIT = 65535
42
+ DEFAULT_CHANNEL_MAX = CHANNEL_MAX_LIMIT
39
43
 
40
44
  # backwards compatibility
41
45
  # @private
@@ -78,7 +82,7 @@ module Bunny
78
82
 
79
83
  # @return [Bunny::Transport]
80
84
  attr_reader :transport
81
- attr_reader :status, :host, :port, :heartbeat, :user, :pass, :vhost, :frame_max, :threaded
85
+ attr_reader :status, :host, :port, :heartbeat, :user, :pass, :vhost, :frame_max, :channel_max, :threaded
82
86
  attr_reader :server_capabilities, :server_properties, :server_authentication_mechanisms, :server_locales
83
87
  attr_reader :default_channel
84
88
  attr_reader :channel_id_allocator
@@ -149,7 +153,9 @@ module Bunny
149
153
 
150
154
  # these are negotiated with the broker during the connection tuning phase
151
155
  @client_frame_max = opts.fetch(:frame_max, DEFAULT_FRAME_MAX)
152
- @client_channel_max = opts.fetch(:channel_max, 65536)
156
+ @client_channel_max = normalize_client_channel_max(opts.fetch(:channel_max, DEFAULT_CHANNEL_MAX))
157
+ # will be-renegotiated during connection tuning steps. MK.
158
+ @channel_max = @client_channel_max
153
159
  @client_heartbeat = self.heartbeat_from(opts)
154
160
 
155
161
  @client_properties = opts[:properties] || DEFAULT_CLIENT_PROPERTIES
@@ -646,6 +652,8 @@ module Bunny
646
652
  UnexpectedFrame
647
653
  when 506 then
648
654
  ResourceError
655
+ when 530 then
656
+ NotAllowedError
649
657
  when 541 then
650
658
  InternalError
651
659
  else
@@ -937,7 +945,25 @@ module Bunny
937
945
  initialize_heartbeat_sender
938
946
  end
939
947
 
940
- raise "could not open connection: server did not respond with connection.open-ok" unless connection_open_ok.is_a?(AMQ::Protocol::Connection::OpenOk)
948
+ unless connection_open_ok.is_a?(AMQ::Protocol::Connection::OpenOk)
949
+ if connection_open_ok.is_a?(AMQ::Protocol::Connection::Close)
950
+ e = instantiate_connection_level_exception(connection_open_ok)
951
+ begin
952
+ shut_down_all_consumer_work_pools!
953
+ maybe_shutdown_reader_loop
954
+ rescue ShutdownSignal => sse
955
+ # no-op
956
+ rescue Exception => e
957
+ @logger.warn "Caught an exception when cleaning up after receiving connection.close: #{e.message}"
958
+ ensure
959
+ close_transport
960
+ end
961
+
962
+ @origin_thread.raise(e)
963
+ else
964
+ raise "could not open connection: server did not respond with connection.open-ok but #{connection_open_ok.inspect} instead"
965
+ end
966
+ end
941
967
  end
942
968
 
943
969
  def heartbeat_disabled?(val)
@@ -957,6 +983,7 @@ module Bunny
957
983
 
958
984
  # @private
959
985
  def initialize_heartbeat_sender
986
+ maybe_shutdown_heartbeat_sender
960
987
  @logger.debug "Initializing heartbeat sender..."
961
988
  @heartbeat_sender = HeartbeatSender.new(@transport, @logger)
962
989
  @heartbeat_sender.start(@heartbeat)
@@ -1037,6 +1064,24 @@ module Bunny
1037
1064
  Logger::WARN
1038
1065
  end
1039
1066
  end
1067
+
1068
+ # @private
1069
+ def shut_down_all_consumer_work_pools!
1070
+ @channels.each do |_, ch|
1071
+ ch.maybe_kill_consumer_work_pool!
1072
+ end
1073
+ end
1074
+
1075
+ def normalize_client_channel_max(n)
1076
+ return CHANNEL_MAX_LIMIT if n > CHANNEL_MAX_LIMIT
1077
+
1078
+ case n
1079
+ when 0 then
1080
+ CHANNEL_MAX_LIMIT
1081
+ else
1082
+ n
1083
+ end
1084
+ end
1040
1085
  end # Session
1041
1086
 
1042
1087
  # backwards compatibility
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Bunny
4
4
  # @return [String] Version of the library
5
- VERSION = "1.0.4"
5
+ VERSION = "1.0.5"
6
6
  end
@@ -147,6 +147,25 @@ describe Bunny::Session do
147
147
  end
148
148
  end
149
149
 
150
+ context "initialized with :channel_max => 4096" do
151
+ after :each do
152
+ subject.close if subject.open?
153
+ end
154
+
155
+ let(:channel_max) { 1024 }
156
+ let(:subject) { described_class.new(:channel_max => channel_max) }
157
+
158
+ # this assumes RabbitMQ has no lower value configured. In 3.2
159
+ # it is 0 (no limit) by default and 1024 is still a fairly low value
160
+ # for future releases. MK.
161
+ it "negotiates channel max to be 1024" do
162
+ subject.start
163
+ subject.channel_max.should == channel_max
164
+
165
+ subject.close
166
+ end
167
+ end
168
+
150
169
  context "initialized with :ssl => true" do
151
170
  let(:subject) do
152
171
  described_class.new(:user => "bunny_gem",
@@ -38,4 +38,40 @@ describe Bunny::Channel do
38
38
  ch.close
39
39
  end
40
40
  end
41
+
42
+
43
+ context "with a single-threaded connection" do
44
+ let(:connection) do
45
+ c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed", :continuation_timeout => 10000, :threaded => false)
46
+ c.start
47
+ c
48
+ end
49
+
50
+
51
+ context "when publishing with confirms enabled" do
52
+ it "increments delivery index" do
53
+ ch = connection.create_channel
54
+ ch.should_not be_using_publisher_confirmations
55
+
56
+ ch.confirm_select
57
+ ch.should be_using_publisher_confirmations
58
+
59
+ q = ch.queue("", :exclusive => true)
60
+ x = ch.default_exchange
61
+
62
+ n.times do
63
+ x.publish("xyzzy", :routing_key => q.name)
64
+ end
65
+
66
+ ch.next_publish_seq_no.should == n + 1
67
+ ch.wait_for_confirms.should be_true
68
+ sleep 0.25
69
+
70
+ q.message_count.should == n
71
+ q.purge
72
+
73
+ ch.close
74
+ end
75
+ end
76
+ end
41
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.0.4
4
+ version: 1.0.5
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: 2013-11-18 00:00:00.000000000 Z
15
+ date: 2013-11-26 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: amq-protocol
@@ -20,14 +20,14 @@ dependencies:
20
20
  requirements:
21
21
  - - '>='
22
22
  - !ruby/object:Gem::Version
23
- version: 1.8.0
23
+ version: 1.9.0
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
28
  - - '>='
29
29
  - !ruby/object:Gem::Version
30
- version: 1.8.0
30
+ version: 1.9.0
31
31
  description: Easy to use, feature complete Ruby client for RabbitMQ 2.0 and later
32
32
  versions.
33
33
  email:
@@ -224,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
224
  version: '0'
225
225
  requirements: []
226
226
  rubyforge_project:
227
- rubygems_version: 2.1.6
227
+ rubygems_version: 2.1.11
228
228
  signing_key:
229
229
  specification_version: 4
230
230
  summary: Popular easy to use Ruby client for RabbitMQ