bunny 2.9.2 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 10f9758e67c181d0b2066f29dae89a4eec11ca8f
4
- data.tar.gz: 2f515bc91583877f6a13fa33085ed0069260fcdb
3
+ metadata.gz: a1383ed91ffd30856f2d5a7581dcc0c4110c072b
4
+ data.tar.gz: d90f995da1275458c90e2659a005aaa555a53300
5
5
  SHA512:
6
- metadata.gz: 5ef6792e9f0d3ee42eeee11cac8dd0d758dc43f126fcbc1c8989d185c714bdce35120d6422c340f389acc4441a7f07a1fe53aacabf2f3eba23ccd43afffb7156
7
- data.tar.gz: 83ca932cf5981a08e6c1fe561f6762b95c61a07968a6b60770f88a6124184d58692f8a13bf66c422734471c49b5bd6c35ec021eda5b87620cf13fdf3190ab2f3
6
+ metadata.gz: 2de02f1c102d95da9137f4348f1e4897d2848cb2851f6fb51ebae28cf48b39c103c87b3faffc05b6b98db2482aab8c8a765204f9ce8d264ebe23feb34ba8913b
7
+ data.tar.gz: 3a1807d8219e9a006176ffeccba1120d5b3f6d237db750cfcd50ae7f5951d1481ffa90bec94dc700fc2f221aefe110da84910ab381a473ca7851ad127b6cacc3
@@ -1,13 +1,16 @@
1
1
  language: ruby
2
2
  bundler_args: --without development
3
3
  cache: bundler
4
+ before_install:
5
+ - gem install bundler
4
6
  before_script: "./bin/ci/before_build"
5
7
  script: "bundle exec rake integration_without_recovery"
6
8
  rvm:
7
9
  - ruby-head
8
- - "2.4.1"
9
- - "2.3.4"
10
- - "2.2.7"
10
+ - "2.5.1"
11
+ - "2.4.2"
12
+ - "2.3.5"
13
+ - "2.2.8"
11
14
  notifications:
12
15
  email: michael@rabbitmq.com
13
16
  services:
@@ -15,6 +18,11 @@ services:
15
18
  branches:
16
19
  only:
17
20
  - master
18
- - 2.6.x-stable
21
+ - 2.9.x-stable
22
+ - 2.8.x-stable
19
23
  env:
20
24
  - CI=true
25
+ matrix:
26
+ allow_failures:
27
+ rvm:
28
+ - ruby-head
@@ -1,13 +1,68 @@
1
- ## Changes between Bunny 2.9.1 and 2.9.2 (unreleased)
1
+ ## Changes between Bunny 2.10.0 and 2.11.0 (unreleased)
2
2
 
3
3
  No changes yet.
4
4
 
5
5
 
6
- ## Changes between Bunny 2.9.0 and 2.9.1 (Jan 11th, 2018)
6
+ ## Changes between Bunny 2.9.0 and 2.10.0 (Jun 5th, 2018)
7
7
 
8
- ### Default CA Certificate Paths are Respected Again
8
+ `2.10.0` is a maintenance release that introduces a couple of
9
+ **minor potentially breaking changes**.
9
10
 
10
- GitHub issue: [#539](https://github.com/ruby-amqp/bunny/issues/539).
11
+ ### Disabling Heartbeats Also Disables TCP Socket Read Timeouts
12
+
13
+ Disabling heartbeats will now disable TCP socket read timeouts.
14
+
15
+ They go hand in hand and users who prefer TCP keepalives via
16
+ kernel configuration previously had to also explicitly configure
17
+ a zero read timeout.
18
+
19
+ GitHub issue: [#551](https://github.com/ruby-amqp/bunny/pull/551).
20
+
21
+ Contributed by Carl Hörberg.
22
+
23
+
24
+ ### `verify_peer: false` Has the Expected Effect Again
25
+
26
+ Make sure `verify_peer: false` has the expected effect again.
27
+
28
+ Default value of connection's `:verify_peer` option to `true` only when
29
+ all of `:verify_ssl`, `:verify_peer`, and `:verify` are `nil`.
30
+
31
+ GitHub issue: [#541](https://github.com/ruby-amqp/bunny/issues/541).
32
+
33
+ Contributed by Howard Ding.
34
+
35
+
36
+ ### Maximum Number of Channels Limited to 2K by Default
37
+
38
+ Default maximum number of channels is limited to 2047 to reduce the probability
39
+ of severe channel leaks. See [rabbitmq/rabbitmq-server#1593](https://github.com/rabbitmq/rabbitmq-server/issues/1593) for details.
40
+
41
+ Applications that want to use more channels per connection can still configure a higher value
42
+ using the `channel_max` setting (for both Bunny and RabbitMQ server).
43
+
44
+ GitHub issue: [#553](https://github.com/ruby-amqp/bunny/pull/553).
45
+
46
+
47
+
48
+ ### Squashed Some Warnings
49
+
50
+ GitHub issue: [#552](https://github.com/ruby-amqp/bunny/pull/552).
51
+
52
+ Contributed by @utilum.
53
+
54
+
55
+
56
+ ### Disabling Heartbeats Disables TCP Socket Read Timeouts
57
+
58
+ Disabling heartbeats will also disable TCP socket read timeouts,
59
+ since the two are effectively interconnected. In this case a mechanism
60
+ such as [TCP keepalives](http://www.rabbitmq.com/heartbeats.html#tcp-keepalives) is assumed to be used.
61
+
62
+ See [RabbitMQ heartbeats guide](http://www.rabbitmq.com/heartbeats.html) for a more
63
+ detailed overview of the options.
64
+
65
+ GH issue: [#519](https://github.com/ruby-amqp/bunny/issues/519).
11
66
 
12
67
  Contributed by Carl Hörberg.
13
68
 
@@ -19,12 +74,23 @@ Contributed by Carl Hörberg.
19
74
  Bunny now requires Ruby 2.2.
20
75
 
21
76
 
22
- ### Support for Additional URI Query Parameters
77
+ ### Connection Recovery Now Retries on Timeouts
78
+
79
+ Connection recovery now will retry on TCP connection timeouts.
80
+
81
+ GitHub issue: [#537](https://github.com/ruby-amqp/bunny/pull/537).
23
82
 
24
- GitHub issue: [#534](https://github.com/ruby-amqp/bunny/pull/534).
83
+
84
+ ### More URI Query Parameters
85
+
86
+ Bunny now supports more URI query parameters plus aliases
87
+ that are identical to those of the server.
25
88
 
26
89
  Contributed by Andrew Babichev.
27
90
 
91
+ GitHub issue: [#534](https://github.com/ruby-amqp/bunny/pull/534)
92
+
93
+
28
94
 
29
95
  ## Changes between Bunny 2.7.0 and 2.8.0 (Dec 18th, 2018)
30
96
 
data/README.md CHANGED
@@ -48,7 +48,7 @@ Specific examples:
48
48
 
49
49
  Modern Bunny versions support
50
50
 
51
- * CRuby 2.0 through 2.4
51
+ * CRuby 2.2 through 2.5 (inclusive)
52
52
 
53
53
  Bunny works sufficiently well on JRuby but there are known
54
54
  JRuby bugs in versions prior to JRuby 9000 that cause high CPU burn. JRuby users should
@@ -95,7 +95,7 @@ gem install bunny
95
95
  To use Bunny in a project managed with Bundler:
96
96
 
97
97
  ``` ruby
98
- gem "bunny", ">= 2.8.0"
98
+ gem "bunny", ">= 2.9.2"
99
99
  ```
100
100
 
101
101
 
@@ -169,6 +169,17 @@ module Bunny
169
169
  @connection = connection
170
170
  @logger = connection.logger
171
171
  @id = id || @connection.next_channel_id
172
+
173
+ # channel allocator is exhausted
174
+ if @id < 0
175
+ msg = "Cannot open a channel: max number of channels on connection reached. Connection channel_max value: #{@connection.channel_max}"
176
+ @logger.error(msg)
177
+
178
+ raise msg
179
+ else
180
+ @logger.debug { "Allocated channel id: #{@id}" }
181
+ end
182
+
172
183
  @status = :opening
173
184
 
174
185
  @connection.register_channel(self)
@@ -17,7 +17,9 @@ module Bunny
17
17
  #
18
18
 
19
19
  # @param [Integer] max_channel Max allowed channel id
20
- def initialize(max_channel = ((1 << 16) - 1))
20
+ def initialize(max_channel = ((1 << 11) - 1))
21
+ # channel 0 has special meaning in the protocol, so start
22
+ # allocator at 1
21
23
  @allocator = AMQ::IntAllocator.new(1, max_channel)
22
24
  @mutex = Monitor.new
23
25
  end
@@ -107,7 +107,7 @@ module Bunny
107
107
  end
108
108
 
109
109
  end
110
- rescue LoadError => le
110
+ rescue LoadError
111
111
  puts "Could not load OpenSSL"
112
112
  end
113
113
  end
@@ -36,10 +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.
39
+ # Hard limit the user cannot go over regardless of server configuration.
40
40
  # @private
41
41
  CHANNEL_MAX_LIMIT = 65535
42
- DEFAULT_CHANNEL_MAX = CHANNEL_MAX_LIMIT
42
+ DEFAULT_CHANNEL_MAX = 2047
43
43
 
44
44
  # backwards compatibility
45
45
  # @private
@@ -101,7 +101,7 @@ module Bunny
101
101
  # @option connection_string_or_opts [String] :username ("guest") Username
102
102
  # @option connection_string_or_opts [String] :password ("guest") Password
103
103
  # @option connection_string_or_opts [String] :vhost ("/") Virtual host to use
104
- # @option connection_string_or_opts [Integer, Symbol] :heartbeat (:server) Heartbeat interval. :server means use the default suggested by RabbitMQ. 0 means no heartbeat (not recommended).
104
+ # @option connection_string_or_opts [Integer, Symbol] :heartbeat (:server) Heartbeat interval. :server means use the default suggested by RabbitMQ. 0 means heartbeats and socket read timeouts will be disabled (not recommended).
105
105
  # @option connection_string_or_opts [Integer] :network_recovery_interval (4) Recovery interval periodic network recovery will use. This includes initial pause after network failure.
106
106
  # @option connection_string_or_opts [Boolean] :tls (false) Should TLS/SSL be used?
107
107
  # @option connection_string_or_opts [String] :tls_cert (nil) Path to client TLS/SSL certificate file (.pem)
@@ -109,9 +109,10 @@ module Bunny
109
109
  # @option connection_string_or_opts [Array<String>] :tls_ca_certificates Array of paths to TLS/SSL CA files (.pem), by default detected from OpenSSL configuration
110
110
  # @option connection_string_or_opts [String] :verify_peer (true) Whether TLS peer verification should be performed
111
111
  # @option connection_string_or_opts [Symbol] :tls_version (negotiated) What TLS version should be used (:TLSv1, :TLSv1_1, or :TLSv1_2)
112
+ # @option connection_string_or_opts [Integer] :channel_max (2047) Maximum number of channels allowed on this connection, minus 1 to account for the special channel 0.
112
113
  # @option connection_string_or_opts [Integer] :continuation_timeout (15000) Timeout for client operations that expect a response (e.g. {Bunny::Queue#get}), in milliseconds.
113
114
  # @option connection_string_or_opts [Integer] :connection_timeout (30) Timeout in seconds for connecting to the server.
114
- # @option connection_string_or_opts [Integer] :read_timeout (30) TCP socket read timeout in seconds.
115
+ # @option connection_string_or_opts [Integer] :read_timeout (30) TCP socket read timeout in seconds. If heartbeats are disabled this will be ignored.
115
116
  # @option connection_string_or_opts [Integer] :write_timeout (30) TCP socket write timeout in seconds.
116
117
  # @option connection_string_or_opts [Proc] :hosts_shuffle_strategy A Proc that reorders a list of host strings, defaults to Array#shuffle
117
118
  # @option connection_string_or_opts [Logger] :logger The logger. If missing, one is created using :log_file and :log_level.
@@ -1068,7 +1069,9 @@ module Bunny
1068
1069
  # threads publish on the same channel aggressively, at some point frames will be
1069
1070
  # delivered out of order and broker will raise 505 UNEXPECTED_FRAME exception.
1070
1071
  # If we synchronize on the channel, however, this is both thread safe and pretty fine-grained
1071
- # locking. Note that "single frame" methods do not need this kind of synchronization. MK.
1072
+ # locking. Note that "single frame" methods technically do not need this kind of synchronization
1073
+ # (no incorrect frame interleaving of the same kind as with basic.publish isn't possible) but we
1074
+ # still recommend not sharing channels between threads except for consumer-only cases in the docs. MK.
1072
1075
  channel.synchronize do
1073
1076
  # see rabbitmq/rabbitmq-server#156
1074
1077
  data = frames.reduce("") { |acc, frame| acc << frame.encode }
@@ -1087,7 +1090,7 @@ module Bunny
1087
1090
  # threads publish on the same channel aggressively, at some point frames will be
1088
1091
  # delivered out of order and broker will raise 505 UNEXPECTED_FRAME exception.
1089
1092
  # If we synchronize on the channel, however, this is both thread safe and pretty fine-grained
1090
- # locking. Note that "single frame" methods do not need this kind of synchronization. MK.
1093
+ # locking. See a note about "single frame" methods in a comment in `send_frameset`. MK.
1091
1094
  channel.synchronize do
1092
1095
  frames.each { |frame| self.send_frame_without_timeout(frame, false) }
1093
1096
  signal_activity!
@@ -1177,26 +1180,18 @@ module Bunny
1177
1180
  @logger.debug { "Heartbeat interval negotiation: client = #{@client_heartbeat}, server = #{connection_tune.heartbeat}, result = #{@heartbeat}" }
1178
1181
  @logger.info "Heartbeat interval used (in seconds): #{@heartbeat}"
1179
1182
 
1180
- # We set the read_write_timeout to twice the heartbeat value
1183
+ # We set the read_write_timeout to twice the heartbeat value,
1184
+ # and then some padding for edge cases.
1181
1185
  # This allows us to miss a single heartbeat before we time out the socket.
1182
- #
1183
- # Since RabbitMQ can be configured to disable heartbeats (bad idea but technically
1184
- # possible nonetheless), we need to take both client and server values into
1185
- # consideration when deciding about using the heartbeat value for read timeouts.
1186
- @transport.read_timeout = if heartbeat_disabled?(@client_heartbeat) || heartbeat_disabled?(@heartbeat)
1187
- @logger.debug { "Will use default socket read timeout of #{Transport::DEFAULT_READ_TIMEOUT}" }
1188
- Transport::DEFAULT_READ_TIMEOUT
1189
- else
1190
- # pad to account for edge cases. MK.
1191
- n = @heartbeat * 2.2
1192
- @logger.debug { "Will use socket read timeout of #{n}" }
1193
- n
1194
- end
1195
-
1186
+ # If heartbeats are disabled, assume that TCP keepalives or a similar mechanism will be used
1187
+ # and disable socket read timeouts. See ruby-amqp/bunny#551.
1188
+ @transport.read_timeout = @heartbeat * 2.2
1189
+ @logger.debug { "Will use socket read timeout of #{@transport.read_timeout}" }
1196
1190
 
1197
1191
  # if there are existing channels we've just recovered from
1198
1192
  # a network failure and need to fix the allocated set. See issue 205. MK.
1199
1193
  if @channels.empty?
1194
+ @logger.debug { "Initializing channel ID allocator with channel_max = #{@channel_max}" }
1200
1195
  @channel_id_allocator = ChannelIdAllocator.new(@channel_max)
1201
1196
  end
1202
1197
 
@@ -29,6 +29,10 @@ module Bunny
29
29
  attr_reader :tls_context, :verify_peer, :tls_ca_certificates, :tls_certificate_path, :tls_key_path
30
30
 
31
31
  attr_writer :read_timeout
32
+ def read_timeout=(v)
33
+ @read_timeout = v
34
+ @read_timeout = nil if @read_timeout == 0
35
+ end
32
36
 
33
37
  def initialize(session, host, port, opts)
34
38
  @session = session
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Bunny
4
4
  # @return [String] Version of the library
5
- VERSION = "2.9.2"
5
+ VERSION = "2.10.0"
6
6
  end
@@ -1,6 +1,8 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require "spec_helper"
3
3
 
4
+ require "socket"
5
+
4
6
  unless ENV["CI"]
5
7
  CERTIFICATE_DIR = ENV.fetch("BUNNY_CERTIFICATE_DIR", "./spec/tls")
6
8
  puts "Will use certificates from #{CERTIFICATE_DIR}"
@@ -35,7 +37,7 @@ unless ENV["CI"]
35
37
  end
36
38
 
37
39
  def local_hostname
38
- ENV.fetch("BUNNY_RABBITMQ_HOSTNAME", "127.0.0.1")
40
+ ENV.fetch("BUNNY_RABBITMQ_HOSTNAME", "localhost")
39
41
  end
40
42
 
41
43
  context "initialized with :tls => true" do
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: 2.9.2
4
+ version: 2.10.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: 2018-02-22 00:00:00.000000000 Z
15
+ date: 2018-06-05 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: amq-protocol
@@ -232,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
232
232
  version: '0'
233
233
  requirements: []
234
234
  rubyforge_project:
235
- rubygems_version: 2.6.14
235
+ rubygems_version: 2.6.11
236
236
  signing_key:
237
237
  specification_version: 4
238
238
  summary: Popular easy to use Ruby client for RabbitMQ