bunny 2.2.2 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -10
- data/ChangeLog.md +26 -6
- data/LICENSE +1 -1
- data/README.md +4 -4
- data/examples/connection/channel_level_exception.rb +0 -8
- data/examples/guides/extensions/alternate_exchange.rb +2 -0
- data/examples/guides/getting_started/hello_world.rb +2 -0
- data/examples/guides/getting_started/weathr.rb +2 -0
- data/examples/guides/queues/one_off_consumer.rb +2 -0
- data/examples/guides/queues/redeliveries.rb +2 -0
- data/lib/bunny/channel.rb +11 -11
- data/lib/bunny/consumer_work_pool.rb +4 -1
- data/lib/bunny/exceptions.rb +1 -1
- data/lib/bunny/heartbeat_sender.rb +1 -1
- data/lib/bunny/session.rb +11 -12
- data/lib/bunny/transport.rb +2 -2
- data/lib/bunny/version.rb +1 -1
- data/spec/higher_level_api/integration/basic_consume_spec.rb +5 -0
- data/spec/higher_level_api/integration/connection_recovery_spec.rb +2 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e10debc2fea6cb3ed014eeebdef45e41e7dad3b4
|
4
|
+
data.tar.gz: 12d0bb9c3a0878b4831c2fe448fe09a0a0207c6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac653c25bc8bd4b8da57e68e0f077f2466eb374da3427f24a9ce62d87cd980246d1785728cf55969d90806bee886390f4ec625732a65903722704d8faa0308f3
|
7
|
+
data.tar.gz: b7d5b2b007e2f1a13240f44df4bcb302155f4d4333950d73ec38e492f3526e971fc2094963489c68af0f13664c906c00eb793dc195ded4d3f829ba7e4d0bd550
|
data/.travis.yml
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
language: ruby
|
2
2
|
bundler_args: --without development
|
3
|
+
cache: bundler
|
3
4
|
before_script: "./bin/ci/before_build"
|
4
5
|
script: "bundle exec rspec -cf documentation spec"
|
5
6
|
rvm:
|
6
|
-
- "2.
|
7
|
-
- "2.
|
8
|
-
- "2.0"
|
9
|
-
- "jruby"
|
10
|
-
- "rbx"
|
7
|
+
- "2.3.0"
|
8
|
+
- "2.2.2"
|
11
9
|
notifications:
|
12
10
|
email: michael@rabbitmq.com
|
13
11
|
services:
|
@@ -15,8 +13,3 @@ services:
|
|
15
13
|
branches:
|
16
14
|
only:
|
17
15
|
- master
|
18
|
-
- 1.4.x-stable
|
19
|
-
matrix:
|
20
|
-
allow_failures:
|
21
|
-
- rvm: rbx
|
22
|
-
- rvm: jruby
|
data/ChangeLog.md
CHANGED
@@ -1,12 +1,21 @@
|
|
1
|
-
## Changes between Bunny 2.2.
|
1
|
+
## Changes between Bunny 2.2.0 and 2.3.0 (Feb 26th, 2016)
|
2
2
|
|
3
|
-
###
|
3
|
+
### Thread#abort_on_exception Setting for Consumer Work Pool Threads
|
4
|
+
|
5
|
+
`Bunny::Session#create_channel` now supports a 3rd argument that,
|
6
|
+
when set to `true`, makes consumer work pool threads to have
|
7
|
+
`Thread#abort_on_exception` set on them.
|
8
|
+
|
9
|
+
Contributed by Seamus Abshere.
|
4
10
|
|
5
|
-
|
6
|
-
bug fixes.
|
11
|
+
### Explicit Transport Closure on Recovery
|
7
12
|
|
13
|
+
Bunny now will explicitly close previosly used transport before starting
|
14
|
+
connection recovery.
|
8
15
|
|
9
|
-
|
16
|
+
GitHub issue: [#377](https://github.com/ruby-amqp/bunny/pull/377).
|
17
|
+
|
18
|
+
Contributed by bkanhoopla.
|
10
19
|
|
11
20
|
### No TLS Socket Double-init
|
12
21
|
|
@@ -16,9 +25,15 @@ GH issue: [#345](https://github.com/ruby-amqp/bunny/issues/345).
|
|
16
25
|
|
17
26
|
Contributed by Carl Hörberg.
|
18
27
|
|
28
|
+
### Lazily Evaluated Debug Log Strings
|
29
|
+
|
30
|
+
GH issue: [#375](https://github.com/ruby-amqp/bunny/pull/375)
|
31
|
+
|
32
|
+
Contributed by Omer Katz.
|
19
33
|
|
20
34
|
|
21
|
-
|
35
|
+
|
36
|
+
## Changes between Bunny 2.1.0 and 2.2.0 (Sep 6th, 2015)
|
22
37
|
|
23
38
|
### Add :addresses to connect options
|
24
39
|
|
@@ -26,6 +41,8 @@ Before this the connection options only allowed multiple hosts, an
|
|
26
41
|
address is a combination of a host and a port. This makes it possible to
|
27
42
|
specify different hosts with different ports.
|
28
43
|
|
44
|
+
Contributed by Bart van Zon (Tele2).
|
45
|
+
|
29
46
|
### Recover from connection.close by default
|
30
47
|
|
31
48
|
Bunny will now try to reconnect also when server sent connection.close is
|
@@ -33,6 +50,9 @@ received, e.g. when a server is restarting (but also when the connection is
|
|
33
50
|
force closed by the server). This is in-line with how many other clients behave.
|
34
51
|
The old default was `recover_from_connection_close: false`.
|
35
52
|
|
53
|
+
Contributed by Carl Hörberg (CloudAMQP).
|
54
|
+
|
55
|
+
|
36
56
|
## Changes between Bunny 2.0.0 and 2.1.0
|
37
57
|
|
38
58
|
Bunny 2.1.0 has an **important breaking change**. It is highly
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2009 –
|
1
|
+
Copyright (c) 2009 – 2016 Chris Duncan, Jakub Stastny aka botanicus,
|
2
2
|
Michael S. Klishin, Eric Lindvall, Stefan Kaes and contributors.
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining
|
data/README.md
CHANGED
@@ -51,7 +51,7 @@ Modern Bunny versions support
|
|
51
51
|
* CRuby 2.2, 2.1, 2.0
|
52
52
|
|
53
53
|
Bunny works sufficiently well on JRuby but there are known
|
54
|
-
JRuby bugs that cause high CPU burn. JRuby users should
|
54
|
+
JRuby bugs in versions prior to JRuby 9000 that cause high CPU burn. JRuby users should
|
55
55
|
use [March Hare](http://rubymarchhare.info).
|
56
56
|
|
57
57
|
Bunny `1.7.x` was the last version to support CRuby 1.9.3 and 1.8.7
|
@@ -88,7 +88,7 @@ gem install bunny
|
|
88
88
|
To use Bunny in a project managed with Bundler:
|
89
89
|
|
90
90
|
``` ruby
|
91
|
-
gem "bunny", ">= 2.
|
91
|
+
gem "bunny", ">= 2.2.2"
|
92
92
|
```
|
93
93
|
|
94
94
|
|
@@ -158,9 +158,9 @@ Other documentation guides are available at [rubybunny.info](http://rubybunny.in
|
|
158
158
|
to also join the [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users) mailing list. Feel free to ask any questions that you may have.
|
159
159
|
|
160
160
|
|
161
|
-
|
161
|
+
## Continuous Integration
|
162
162
|
|
163
|
-
|
163
|
+
[![Build Status](https://travis-ci.org/ruby-amqp/bunny.png)](https://travis-ci.org/ruby-amqp/bunny/)
|
164
164
|
|
165
165
|
|
166
166
|
### News & Announcements on Twitter
|
@@ -11,14 +11,6 @@ require 'bunny'
|
|
11
11
|
conn = Bunny.new(:heartbeat_interval => 8)
|
12
12
|
conn.start
|
13
13
|
|
14
|
-
begin
|
15
|
-
ch1 = conn.create_channel
|
16
|
-
ch1.queue_delete("queue_that_should_not_exist#{rand}")
|
17
|
-
rescue Bunny::NotFound => e
|
18
|
-
puts "Channel-level exception! Code: #{e.channel_close.reply_code}, message: #{e.channel_close.reply_text}"
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
14
|
begin
|
23
15
|
ch2 = conn.create_channel
|
24
16
|
q = "bunny.examples.recovery.q#{rand}"
|
data/lib/bunny/channel.rb
CHANGED
@@ -618,14 +618,14 @@ module Bunny
|
|
618
618
|
# implementation (and even more correct and convenient ones, such as wait/notify, should
|
619
619
|
# we implement them). So we return a triple of nils immediately which apps should be
|
620
620
|
# able to handle anyway as "got no message, no need to act". MK.
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
621
|
+
last_basic_get_response = if @connection.open?
|
622
|
+
wait_on_basic_get_continuations
|
623
|
+
else
|
624
|
+
[nil, nil, nil]
|
625
|
+
end
|
626
626
|
|
627
627
|
raise_if_continuation_resulted_in_a_channel_error!
|
628
|
-
|
628
|
+
last_basic_get_response
|
629
629
|
end
|
630
630
|
|
631
631
|
# prefetch_count is of type short in the protocol. MK.
|
@@ -705,7 +705,7 @@ module Bunny
|
|
705
705
|
#
|
706
706
|
# ch = conn.create_channel
|
707
707
|
# q.subscribe do |delivery_info, properties, payload|
|
708
|
-
# #
|
708
|
+
# # reject the message
|
709
709
|
# ch.basic_reject(delivery_info.delivery_tag, false)
|
710
710
|
# end
|
711
711
|
#
|
@@ -1488,7 +1488,7 @@ module Bunny
|
|
1488
1488
|
#
|
1489
1489
|
# @api plugin
|
1490
1490
|
def recover_from_network_failure
|
1491
|
-
@logger.debug "Recovering channel #{@id} after network failure"
|
1491
|
+
@logger.debug { "Recovering channel #{@id} after network failure" }
|
1492
1492
|
release_all_continuations
|
1493
1493
|
|
1494
1494
|
recover_prefetch_setting
|
@@ -1544,7 +1544,7 @@ module Bunny
|
|
1544
1544
|
# @api plugin
|
1545
1545
|
def recover_queues
|
1546
1546
|
@queues.values.dup.each do |q|
|
1547
|
-
@logger.debug "Recovering queue #{q.name}"
|
1547
|
+
@logger.debug { "Recovering queue #{q.name}" }
|
1548
1548
|
q.recover_from_network_failure
|
1549
1549
|
end
|
1550
1550
|
end
|
@@ -1555,7 +1555,7 @@ module Bunny
|
|
1555
1555
|
# @api plugin
|
1556
1556
|
def recover_consumers
|
1557
1557
|
unless @consumers.empty?
|
1558
|
-
@work_pool = ConsumerWorkPool.new(@work_pool.size)
|
1558
|
+
@work_pool = ConsumerWorkPool.new(@work_pool.size, @work_pool.abort_on_exception)
|
1559
1559
|
@work_pool.start
|
1560
1560
|
end
|
1561
1561
|
@consumers.values.dup.each do |c|
|
@@ -1616,7 +1616,7 @@ module Bunny
|
|
1616
1616
|
|
1617
1617
|
# @private
|
1618
1618
|
def handle_method(method)
|
1619
|
-
@logger.debug "Channel#handle_frame on channel #{@id}: #{method.inspect}"
|
1619
|
+
@logger.debug { "Channel#handle_frame on channel #{@id}: #{method.inspect}" }
|
1620
1620
|
case method
|
1621
1621
|
when AMQ::Protocol::Queue::DeclareOk then
|
1622
1622
|
@continuations.push(method)
|
@@ -15,9 +15,11 @@ module Bunny
|
|
15
15
|
|
16
16
|
attr_reader :threads
|
17
17
|
attr_reader :size
|
18
|
+
attr_reader :abort_on_exception
|
18
19
|
|
19
|
-
def initialize(size = 1)
|
20
|
+
def initialize(size = 1, abort_on_exception = false)
|
20
21
|
@size = size
|
22
|
+
@abort_on_exception = abort_on_exception
|
21
23
|
@queue = ::Queue.new
|
22
24
|
@paused = false
|
23
25
|
end
|
@@ -32,6 +34,7 @@ module Bunny
|
|
32
34
|
|
33
35
|
@size.times do
|
34
36
|
t = Thread.new(&method(:run_loop))
|
37
|
+
t.abort_on_exception = true if abort_on_exception
|
35
38
|
@threads << t
|
36
39
|
end
|
37
40
|
|
data/lib/bunny/exceptions.rb
CHANGED
@@ -62,7 +62,7 @@ module Bunny
|
|
62
62
|
now = Time.now
|
63
63
|
|
64
64
|
if now > (@last_activity_time + @interval)
|
65
|
-
@logger.debug "Sending a heartbeat, last activity time: #{@last_activity_time}, interval (s): #{@interval}"
|
65
|
+
@logger.debug { "Sending a heartbeat, last activity time: #{@last_activity_time}, interval (s): #{@interval}" }
|
66
66
|
@transport.write_without_timeout(AMQ::Protocol::HeartbeatFrame.encode)
|
67
67
|
end
|
68
68
|
end
|
data/lib/bunny/session.rb
CHANGED
@@ -86,8 +86,9 @@ module Bunny
|
|
86
86
|
attr_reader :mechanism
|
87
87
|
# @return [Logger]
|
88
88
|
attr_reader :logger
|
89
|
-
# @return [Integer] Timeout for blocking protocol operations (queue.declare, queue.bind, etc), in milliseconds. Default is
|
89
|
+
# @return [Integer] Timeout for blocking protocol operations (queue.declare, queue.bind, etc), in milliseconds. Default is 15000.
|
90
90
|
attr_reader :continuation_timeout
|
91
|
+
attr_reader :network_recovery_interval
|
91
92
|
|
92
93
|
|
93
94
|
# @param [String, Hash] connection_string_or_opts Connection string or a hash of connection options
|
@@ -107,7 +108,7 @@ module Bunny
|
|
107
108
|
# @option connection_string_or_opts [String] :tls_key (nil) Path to client TLS/SSL private key file (.pem)
|
108
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
|
109
110
|
# @option connection_string_or_opts [String] :verify_peer (true) Whether TLS peer verification should be performed
|
110
|
-
# @option connection_string_or_opts [Integer] :continuation_timeout (
|
111
|
+
# @option connection_string_or_opts [Integer] :continuation_timeout (15000) Timeout for client operations that expect a response (e.g. {Bunny::Queue#get}), in milliseconds.
|
111
112
|
# @option connection_string_or_opts [Integer] :connection_timeout (5) Timeout in seconds for connecting to the server.
|
112
113
|
# @option connection_string_or_opts [Proc] :hosts_shuffle_strategy A Proc that reorders a list of host strings, defaults to Array#shuffle
|
113
114
|
# @option connection_string_or_opts [Logger] :logger The logger. If missing, one is created using :log_file and :log_level.
|
@@ -330,14 +331,14 @@ module Bunny
|
|
330
331
|
# opened (this operation is very fast and inexpensive).
|
331
332
|
#
|
332
333
|
# @return [Bunny::Channel] Newly opened channel
|
333
|
-
def create_channel(n = nil, consumer_pool_size = 1)
|
334
|
+
def create_channel(n = nil, consumer_pool_size = 1, consumer_pool_abort_on_exception = false)
|
334
335
|
raise ArgumentError, "channel number 0 is reserved in the protocol and cannot be used" if 0 == n
|
335
336
|
|
336
337
|
@channel_mutex.synchronize do
|
337
338
|
if n && (ch = @channels[n])
|
338
339
|
ch
|
339
340
|
else
|
340
|
-
ch = Bunny::Channel.new(self, n, ConsumerWorkPool.new(consumer_pool_size || 1))
|
341
|
+
ch = Bunny::Channel.new(self, n, ConsumerWorkPool.new(consumer_pool_size || 1, consumer_pool_abort_on_exception))
|
341
342
|
ch.open
|
342
343
|
ch
|
343
344
|
end
|
@@ -547,7 +548,7 @@ module Bunny
|
|
547
548
|
#
|
548
549
|
# @private
|
549
550
|
def handle_frame(ch_number, method)
|
550
|
-
@logger.debug "Session#handle_frame on #{ch_number}: #{method.inspect}"
|
551
|
+
@logger.debug { "Session#handle_frame on #{ch_number}: #{method.inspect}" }
|
551
552
|
case method
|
552
553
|
when AMQ::Protocol::Channel::OpenOk then
|
553
554
|
@continuations.push(method)
|
@@ -636,6 +637,7 @@ module Bunny
|
|
636
637
|
@channels.each do |n, ch|
|
637
638
|
ch.maybe_kill_consumer_work_pool!
|
638
639
|
end
|
640
|
+
@reader_loop.stop if @reader_loop
|
639
641
|
maybe_shutdown_heartbeat_sender
|
640
642
|
|
641
643
|
recover_from_network_failure
|
@@ -695,9 +697,6 @@ module Bunny
|
|
695
697
|
|
696
698
|
# @private
|
697
699
|
def recover_channels
|
698
|
-
# default channel is reopened right after connection
|
699
|
-
# negotiation is completed, so make sure we do not try to open
|
700
|
-
# it twice. MK.
|
701
700
|
@channels.each do |n, ch|
|
702
701
|
ch.open
|
703
702
|
|
@@ -934,7 +933,7 @@ module Bunny
|
|
934
933
|
end
|
935
934
|
end
|
936
935
|
|
937
|
-
# Sends multiple frames, one
|
936
|
+
# Sends multiple frames, in one go. For thread safety this method takes a channel
|
938
937
|
# object and synchronizes on it.
|
939
938
|
#
|
940
939
|
# @private
|
@@ -1049,7 +1048,7 @@ module Bunny
|
|
1049
1048
|
else
|
1050
1049
|
negotiate_value(@client_heartbeat, connection_tune.heartbeat)
|
1051
1050
|
end
|
1052
|
-
@logger.debug "Heartbeat interval negotiation: client = #{@client_heartbeat}, server = #{connection_tune.heartbeat}, result = #{@heartbeat}"
|
1051
|
+
@logger.debug { "Heartbeat interval negotiation: client = #{@client_heartbeat}, server = #{connection_tune.heartbeat}, result = #{@heartbeat}" }
|
1053
1052
|
@logger.info "Heartbeat interval used (in seconds): #{@heartbeat}"
|
1054
1053
|
|
1055
1054
|
# We set the read_write_timeout to twice the heartbeat value
|
@@ -1069,9 +1068,9 @@ module Bunny
|
|
1069
1068
|
end
|
1070
1069
|
|
1071
1070
|
@transport.send_frame(AMQ::Protocol::Connection::TuneOk.encode(@channel_max, @frame_max, @heartbeat))
|
1072
|
-
@logger.debug "Sent connection.tune-ok with heartbeat interval = #{@heartbeat}, frame_max = #{@frame_max}, channel_max = #{@channel_max}"
|
1071
|
+
@logger.debug { "Sent connection.tune-ok with heartbeat interval = #{@heartbeat}, frame_max = #{@frame_max}, channel_max = #{@channel_max}" }
|
1073
1072
|
@transport.send_frame(AMQ::Protocol::Connection::Open.encode(self.vhost))
|
1074
|
-
@logger.debug "Sent connection.open with vhost = #{self.vhost}"
|
1073
|
+
@logger.debug { "Sent connection.open with vhost = #{self.vhost}" }
|
1075
1074
|
|
1076
1075
|
frame2 = begin
|
1077
1076
|
fr = @transport.read_next_frame
|
data/lib/bunny/transport.rb
CHANGED
@@ -458,8 +458,8 @@ but prone man-in-the-middle attacks. Please set :verify_peer => true in producti
|
|
458
458
|
cert_inlines.push(cert)
|
459
459
|
end
|
460
460
|
end
|
461
|
-
@logger.debug "Using CA certificates at #{cert_files.join(', ')}"
|
462
|
-
@logger.debug "Using #{cert_inlines.count} inline CA certificates"
|
461
|
+
@logger.debug { "Using CA certificates at #{cert_files.join(', ')}" }
|
462
|
+
@logger.debug { "Using #{cert_inlines.count} inline CA certificates" }
|
463
463
|
if certs.empty?
|
464
464
|
@logger.error "No CA certificates found, add one with :tls_ca_certificates"
|
465
465
|
end
|
data/lib/bunny/version.rb
CHANGED
@@ -260,7 +260,10 @@ describe Bunny::Queue, "#subscribe" do
|
|
260
260
|
let(:queue_name) { "bunny.basic_consume#{rand}" }
|
261
261
|
|
262
262
|
it "uses exception handler" do
|
263
|
+
caughts = []
|
263
264
|
t = Thread.new do
|
265
|
+
allow(connection.logger).to receive(:error) { |x| caughts << x }
|
266
|
+
|
264
267
|
ch = connection.create_channel
|
265
268
|
q = ch.queue(queue_name, :auto_delete => true, :durable => false)
|
266
269
|
|
@@ -276,6 +279,8 @@ describe Bunny::Queue, "#subscribe" do
|
|
276
279
|
5.times { x.publish("hello", :routing_key => queue_name) }
|
277
280
|
sleep 1.5
|
278
281
|
|
282
|
+
expect(caughts.size).to eq(5)
|
283
|
+
|
279
284
|
ch.close
|
280
285
|
end
|
281
286
|
end
|
@@ -359,6 +359,7 @@ unless ENV["CI"]
|
|
359
359
|
expect(c).not_to be_open
|
360
360
|
|
361
361
|
wait_for_recovery
|
362
|
+
sleep 1
|
362
363
|
expect(ch).to be_open
|
363
364
|
|
364
365
|
expect(q.consumer_count).to eq n
|
@@ -381,6 +382,7 @@ unless ENV["CI"]
|
|
381
382
|
expect(c).not_to be_open
|
382
383
|
|
383
384
|
wait_for_recovery
|
385
|
+
sleep 1
|
384
386
|
expect(ch).to be_open
|
385
387
|
|
386
388
|
qs.each do |q|
|
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.
|
4
|
+
version: 2.3.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:
|
15
|
+
date: 2016-02-26 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: amq-protocol
|
@@ -228,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
228
228
|
version: '0'
|
229
229
|
requirements: []
|
230
230
|
rubyforge_project:
|
231
|
-
rubygems_version: 2.
|
231
|
+
rubygems_version: 2.5.1
|
232
232
|
signing_key:
|
233
233
|
specification_version: 4
|
234
234
|
summary: Popular easy to use Ruby client for RabbitMQ
|