This is a stability improvement release that is completely backwards compatible
with 0.9.0.
We encourage all Bunny users to upgrade to it.
Changes between Bunny 0.9.1 and 0.9.2
Reliability Improvement in Automatic Network Failure Recovery
Bunny now ensures a new connection transport (socket) is initialized
before any recovery is attempted.
Changes between Bunny 0.9.0 and 0.9.1
Reliability Improvement in Bunny::Session#create_channel
Bunny::Session#create_channel now uses two separate mutexes to avoid
a (very rare) issue when the previous implementation would try to
re-acquire the same mutex and fail (Ruby mutexes are non-reentrant).
This release is a ground-up rewrite of Bunny that eliminates a lot of limitations
of earlier versions, adds new features, improves throughput, makes Bunny benefit
from runtime parallelism on Ruby implementations that support it and introduces
other numerous improvements.
It is not entirely backwards compatible, although we’ve tried hard to make upgrading
as seamless as possible.
This is a major step forward for Bunny. The library is now a feature complete,
first class RabbitMQ client.
We encourage all Bunny users to upgrade to it.
Release Highlights
Feature Complete
Bunny 0.9 supports all RabbitMQ 3.x features, including extensions.
If something is possible to do with RabbitMQ over AMQP 0.9.1, you can do it with Bunny 0.9.
No More Limitations
Bunny 0.7.x and 0.8.0 did not support publishing of messages over 128 Kb in size and
had limitations around asynchronous (“push”) consumers.
Bunny 0.9 uses the same protocol serialization library as amqp gem. It has lower memory footprint
and significantly more efficient: serialization throughput increased from 20% to x50 times
compared to Bunny 0.8 serialization code.
Fewer memory allocations mean less GC stress and GC-induced CPU burn.
Concurrency
Bunny uses a separate thread for network activity. Consumers dispatch messages to a thread pool
(by default of size 1) that can be tuned.
On Ruby runtimes that support runtime parallelism, this will increase throughput of both
consumers and publishers on multicore hardware.
This release is a development milestone. 2.0 focuses on usability and introduces a couple of
major API improvements and features.
2.0 should be production ready from the stability perspective but has breaking API changes.
Please consult the change log below before considering upgrading.
Changes Between 1.5.0 and 2.0.0
Hot Bunnies 2.0 has breaking API changes.
Shutdown Callbacks
HotBunnies::Session#on_shutdown and HotBunnies::Channel#on_shutdown are two
new methods that register shutdown hooks. Those are executed when
Network connectivity to RabbitMQ is lost
RabbitMQ shuts down the connection (because of an error or management UI action)
The callbacks take two arguments: the entity that’s being shutdown
(HotBunnies::Session or HotBunnies::Channel) and shutdown reason (an exception):
HotBunnies::Queue#subscribe_with and HotBunnies::Queue#build_consumer are new method
that allow using consumer objects, for example, to first instantiate a blocking consumer
and pass the reference around so it can be cancelled from a different thread later.
Passing a block for the :on_cancellation option to HotBunnies::Queue#subscribe
lets you support RabbitMQ consumer cancellation. The block should take 3
arguments: a channel, a consumer and a consumer tag.
HotBunnies Operations Now Raise Ruby Exceptions
HotBunnies used to expose RabbitMQ Java client’s channel implementation
directly to Ruby code. This means that whenever an exception was raised,
it was a Java exception (commonly java.io.IOException, wrapping a shutdown
signal).
Not only this severely violates the Principle of Least Surprise, it also
makes it much harder to inspect the exception and figure out how to get
relevant information from it without reading the RabbitMQ Java client
source.
Hot Bunnies 2.0+ provides a Ruby implementation of HotBunnies::Channel
which rescues Java exceptions and turns them into Ruby
exceptions.
For example, handling a queue.bind failure now can be demonstrated
with the following straightforward test:
123456789101112131415
context"when the exchange does not exist"doit"raises an exception"doch=connection.create_channelq=ch.queue("",:auto_delete=>true)raised=nilbeginq.bind("asyd8a9d98sa73t78hd9as^&&(&@#(*^")rescueHotBunnies::NotFound=>eraised=eendraised.channel_close.reply_text.should=~/no exchange/endend
or have otherwise meaningful names that follow Bunny names closely:
HotBunnies::PossibleAuthenticationFailureError
HotBunnies::ChannelAlreadyClosed
HotBunnies::Queue#subscribe Now Returns a Consumer
This is a breaking API change
HotBunnies::Queue#subscribe now returns a consumer (a HotBunnies::Consumer instance)
that can be cancelled and contains a consumer tag.
HotBunnies::Subscription was eliminated as redundant. All the same methods are
now available on HotBunnies::Consumer subclasses.
HotBunnies::Queue#subscribe Uses :block => false By Default
This is a breaking API change
HotBunnies::Queue#subscribe now uses :block => false by default, thus
not blocking the caller. This reduces the need to use explicitly
started threads for consumers.
This is also how Bunny 0.9 works and we’ve seen this default to be
a better idea.
RabbitMQ Java Client Upgrade
Hot Bunnies now uses RabbitMQ Java client 3.1.
Plans for 2.0.0 Final
There is still a few things we need to do before HotBunnies 2.0 can be declared complete:
Investigate automatic network failure recovery, like Bunny 0.9
Make TLS support more configurable, ideally with the same API as Bunny 0.9
This release fixes a couple of issues discovered since RC1. Bunny 0.9 is now feature
complete and used widely enough for us to be going through the RC stage.
If you use an earlier Bunny version, please help us test 0.9 RCs!
Changes between Bunny 0.9.0.rc1 and 0.9.0.rc2
Channel Now Properly Restarts Consumer Pool
In a case when all consumers are cancelled, Bunny::Channel
will shut down its consumer delivery thread pool.
It will also now mark the pool as not running so that it can be
started again successfully if new consumers are registered later.
GH issue: #133.
Bunny::Queue#pop_waiting is Removed
A little bit of background: on MRI, the method raised ThreadErrors
reliably. On JRuby, we used a different [internal] queue implementation
from JDK so it wasn’t an issue.
Timeout.timeout uses Thread#kill and Thread#join, both of which
eventually attempt to acquire a mutex used by Queue#pop, which Bunny
currently uses for continuations. The mutex is already has an owner
and so a ThreadError is raised.
This is not a problem on JRuby because there we don’t use Ruby’s
Timeout and Queue and instead rely on a JDK concurrency primitive
which provides “poll with a timeout”.
Finding a workaround will probably take a bit of time and may involve
reimplementing standard library and core classes.
We don’t want this issue to block Bunny 0.9 release. Neither we want
to ship a broken feature. So as a result, we will drop
Bunny::Queue#pop_waiting since it cannot be reliably implemented in a
reasonable amount of time on MRI.
Per issue #131.
More Flexible SSLContext Configuration
Bunny will now upgrade connection to SSL in Bunny::Session#start,
so it is possible to fine tune SSLContext and socket settings
before that:
This release includes one bug fix, removes more long time deprecated code and makes
RabbitMQ extensions being part of the core (so they are always available, no need to load them separately).
Changes Between 1.0.0 and 1.1.0
AMQP::Channel#confirm_select is Now Delayed
AMQP::Channel#confirm_select is now delayed until after the channel
is opened, making it possible to use it with the pseudo-synchronous
code style.
RabbitMQ Extensions are Now in Core
amqp gem has been targeting RabbitMQ exclusively for a while now.
RabbitMQ extensions are now loaded by default and will be even more
tightly integrated in the future.
AMQP::Channel.default is Removed
AMQP::Channel.default and method_missing-based operations on the default
channel has been removed. They’ve been deprecated since 0.6.
AMQP::Channel#rpc is Removed
AMQP::RPC-related code has been removed. It has been deprecated
since 0.7.
AMQP::Channel.on_error is Removed
Long time deprecated AMQP::Channel.on_error is removed.
This release adds TLS support and a couple of minor improvements. Bunny 0.9 is now feature
complete and used widely enough for us to be confident about labelling this an RC.
Changes between Bunny 0.9.0.pre13 and 0.9.0.rc1
TLS Support
Bunny 0.9 finally supports TLS. There are 3 new options Bunny.new takes:
:tls which, when set to true, will set SSL context up and switch to TLS port (5671)
:tls_cert which is a string path to the client certificate (public key) in PEM format
:tls_key which is a string path to the client key (private key) in PEM format
:tls_ca_certificates which is an array of string paths to CA certificates in PEM format
Bunny::Queue#pop_waiting is a new function that mimics Bunny::Queue#pop
but will wait until a message is available. It uses a :timeout option and will
raise an exception if the timeout is hit:
12345678
# given 1 message in the queue,# works exactly as Bunny::Queue#getq.pop_waiting# given no messages in the queue, will wait for up to 0.5 seconds# for a message to become available. Raises an exception if the timeout# is hitq.pop_waiting(:timeout=>0.5)
This method only makes sense for collecting Request/Reply (“RPC”) replies.
Bunny::InvalidCommand is now Bunny::CommandInvalid
Bunny::InvalidCommand is now Bunny::CommandInvalid (follows
the exception class naming convention based on response status
name).
This release fixes a regression that affected consumers and a few minor usability improvements
for “one-off” consumers that cancel themselves.
Changes between Bunny 0.9.0.pre12 and 0.9.0.pre13
Channels Without Consumers Now Tear Down Consumer Pools
Channels without consumers left (when all consumers were cancelled)
will now tear down their consumer work thread pools, thus making
HotBunnies::Queue#subscribe(:block => true) calls unblock.
This is typically the desired behavior.
Consumer and Channel Available In Delivery Handlers
Delivery handlers registered via Bunny::Queue#subscribe now will have
access to the consumer and channel they are associated with via the
delivery_info argument:
1234
q.subscribedo|delivery_info,properties,payload|delivery_info.consumer# => the consumer this delivery is fordelivery_info.consumer# => the channel this delivery is onend
This allows using Bunny::Queue#subscribe for one-off consumers
much easier, including when used with the :block option.
Bunny::Exchange#wait_for_confirms
Bunny::Exchange#wait_for_confirms is a convenience method on Bunny::Exchange that
delegates to the method with the same name on exchange’s channel.
Plans for 0.9.0 Final
There is still a few things we need to do before Bunny 0.9 can be declared complete:
Fix any remaining important issues we get reports for