Ruby RabbitMQ clients blog

News and updates about various Ruby clients for RabbitMQ

Bunny 0.9.0.pre11 Is Released

TL;DR

Bunny 0.9.0.pre11 is released to rubygems.org.

This release includes minor new features, stability and performance improvements. It is backwards compatible.

Changes between Bunny 0.9.0.pre10 and 0.9.0.pre11

Bunny::Session#create_channel Now Accepts Consumer Work Pool Size

Bunny::Session#create_channel now accepts consumer work pool size as the second argument:

1
2
3
# nil means channel id will be allocated by Bunny.
# 8 is the number of threads in the consumer work pool this channel will use.
ch = conn.create_channel(nil, 8)

Heartbeat Fix For Long Running Consumers

Long running consumers that don’t send any data will no longer suffer from connections closed by RabbitMQ because of skipped heartbeats.

Activity tracking now takes sent frames into account.

Time-bound continuations

If a network loop exception causes “main” session thread to never receive a response, methods such as Bunny::Channel#queue will simply time out and raise Timeout::Error now, which can be handled.

It will not start automatic recovery for two reasons:

  • It will be started in the network activity loop anyway
  • It may do more damage than good

Kicking off network recovery manually is a matter of calling Bunny::Session#handle_network_failure.

The main benefit of this implementation is that it will never block the main app/session thread forever, and it is really efficient on JRuby thanks to a j.u.c. blocking queue.

Fixes #112.

Logging Support

Every Bunny connection now has a logger. By default, Bunny will use STDOUT as logging device. This is configurable using the :log_file option:

1
2
3
require "bunny"

conn = Bunny.new(:log_level => :warn)

or the BUNNY_LOG_LEVEL environment variable that can take one of the following values:

  • debug (very verbose)
  • info
  • warn
  • error
  • fatal (least verbose)

Severity is set to warn by default. To disable logging completely, set the level to fatal.

To redirect logging to a file or any other object that can act as an I/O entity, pass it to the :log_file option.

Publishing Performance Improvements

Publishing throughput has been improved by about 10% for messages smaller than 128K. The gains are more substantial on JRuby: improved implementation is easier for JVM to inline.

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
  • Finish TLS support

Michael on behalf of the Ruby RabbitMQ Clients Team

Bunny 0.9.0.pre10 Is Released

TL;DR

Bunny 0.9.0.pre10 is released to rubygems.org.

This is a bug fix release. It includes one breaking API change

Changes between Bunny 0.9.0.pre9 and 0.9.0.pre10

This release contains a breaking API change.

Concurrency Improvements On JRuby

On JRuby, Bunny now will use java.util.concurrent-backed implementations of some of the concurrency primitives. This both improves client stability (JDK concurrency primitives has been around for 9 years and have well-defined, documented semantics) and opens the door to solving some tricky failure handling problems in the future.

Explicitly Closed Sockets

Bunny now will correctly close the socket previous connection had when recovering from network issues.

Bunny::Exception Now Extends StandardError

Bunny::Exception now inherits from StandardError and not Exception.

Naked rescue like this

1
2
3
4
5
begin
  # ...
rescue => e
  # ...
end

catches only descendents of StandardError. Most people don’t know this and this is a very counter-intuitive practice, but apparently there is code out there that can’t be changed that depends on this behavior.

This is a breaking API change.

Plans for 0.9.0 Final

There is still a few things we need to do before Bunny 0.9 can be declared complete:

  • Add logging
  • Finish TLS support
  • Make network failure recovery even more flexible

Michael on behalf of the Ruby RabbitMQ Clients Team

Amqp Gem 1.0.2 Is Released

TL;DR

amqp gem 1.0.2 is released to rubygems.org.

This release has bug fixes.

Changes between amqp gem 1.0.0 and 1.0.2

AMQP::Channel#reuse Fixes

Channels that AMQP::Channel#reuse was called on now properly execute all channel lifecycle callbacks again.

Michael on behalf of the Ruby RabbitMQ Clients Team

Bunny 0.9.0.pre9 Is Released

TL;DR

Bunny 0.9.0.pre9 is released to rubygems.org.

This is a bug fix release. It is 100% backwards compatible.

Changes between Bunny 0.9.0.pre8 and 0.9.0.pre9

Most of the work in this release has gone into investigating and fixing issues that manifested in a high CPU usage spike. In some cases, the issue turned out to be system-specific (e.g. a leap second bug that affected certain kernels and environments such as OpenVZ).

More Reliable Heartbeat Sender

Heartbeat sender no longer slips into an infinite loop if it encounters an exception. Instead, it will just stop (and presumably re-started when the network error recovery kicks in or the app reconnects manually).

Network Recovery After Delay

Network reconnection now kicks in after a delay to avoid aggressive reconnections in situations when we don’t want to endlessly reconnect (e.g. when the connection was closed via the Management UI).

The :network_recovery_interval option passed to Bunny::Session#initialize and Bunny.new controls the interval. Default is 5 seconds.

Default Heartbeat Value Is Now Server-Defined

Bunny will now use heartbeat value provided by RabbitMQ by default.

Plans for 0.9.0 Final

There is still a few things we need to do before Bunny 0.9 can be declared complete:

  • Add logging
  • Finish TLS support
  • Make network failure recovery even more flexible

Michael on behalf of the Ruby RabbitMQ Clients Team

Amqp Gem 1.0.1 Is Released

TL;DR

amqp gem 1.0.1 is released to rubygems.org.

This release has bug fixes by upgrading amq-protocol dependency to 1.3.0+.

Changes between amqp gem 1.0.0 and 1.0.1

amq-protocol Bug Fixes

  • amq-protocol now correctly serializes floats (both 32 and 64 bits) in attribute tables.
  • Byte values (8 bit signed integers) deserialization is now supported.

Michael on behalf of the Ruby RabbitMQ Clients Team

Amqp Gem 1.0 Is Released

Give a programmer a ship and you excite him for a day. Teach him how to ship and you excite him for a lifetime.

– Lao Tzu

TL;DR

amqp gem 1.0.0 is released to rubygems.org. The library is almost 5 years old, has undergone a major refactoring in 0.8.x and evolves like a mature project. It’s time to release 1.0.

This release is 100% backwards compatible with 0.9.x and includes no changes visible to library users.

It’s Time For 1.0

In the last year-and-a-half or so, amqp gem has been evolving like a mature project for a while now. What does that mean? A couple of things:

  • Things don’t change often.
  • Most issues only affect a small % of users and almost always can be classified as edge cases, minor usability issues or Heisenbugs specific to certain systems.

In July 2013, amqp gem will turn 5 years old. It’s a pretty significant age for a library. In these years amqp gem has undergone a major rework in 2010-2011, got pretty solid documentation guides written and has been pretty well battle tested by small and large companies.

It’s only natural to release 1.0.0 instead of bumping 0.9.x patch levels until we reach 0.9.99.

Change log

1.0.0 is based on the master branch which is completely backwards compatible with 0.9.x but removes some long deprecated API elements. In other words, if you are running the most recent 0.9.x release, there is no change log :)

So go ahead and upgrade to 1.0. It’s in better shape than ever before and passed the test of time.

The Future

Does it mean that the work on them gem is done? No, definitely not. RabbitMQ gets new features, people suggest usability improvements and Heisenbugs are discovered by large users every so often.

So you can be sure that amqp gem and its documentation will continue evolving. To keep up-to-date with future releases, join our mailing list, RabbitMQ mailing list and follow @rubyamqp on Twitter.

Supported Ruby Versions

amqp gem 1.0 supports a range of Ruby versions and implementations:

  • CRuby 2.0
  • CRuby 1.9.3
  • CRuby 1.9.2
  • Rubinius 2.0 in both modes
  • JRuby 1.6+ in both modes
  • CRuby 1.8.7, REE

Supported RabbitMQ Versions

amqp gem 1.0 requires RabbitMQ 2.0 or later. 3.x releases are always recommended. Running a recent Erlang/OTP release is also a good idea.

Alternatives

If you are looking for a Ruby RabbitMQ client and amqp gem does not fit your bill, take a look at

Michael on behalf of the Ruby RabbitMQ Clients Team

Bunny 0.9.0.pre8 Is Released

TL;DR

Bunny 0.9.0.pre8 is released to rubygems.org.

This release has bug fixes and (very) minor features. It is 100% backwards compatible.

Changes between Bunny 0.9.0.pre7 and 0.9.0.pre8

Stability Improvements

Several stability improvements in the network layer, connection error handling, and concurrency hazards.

Automatic Connection Recovery Can Be Disabled

Automatic connection recovery now can be disabled by passing the :automatically_recover => false option to Bunny#initialize).

When the recovery is disabled, network I/O-related exceptions will cause an exception to be raised in thee thread the connection was started on.

No Timeout Control For Publishing

Bunny::Exchange#publish and Bunny::Channel#basic_publish no longer perform timeout control (using the timeout module) which roughly increases throughput for flood publishing by 350%.

Apps that need delivery guarantees should use publisher confirms.

Plans for 0.9.0 Final

There is still a few things we need to do before Bunny 0.9 can be declared complete:

  • Add logging
  • Finish TLS support
  • Make network failure recovery even more flexible

Michael on behalf of the Ruby RabbitMQ Clients Team

Amqp Gem 0.9.10 Is Released

TL;DR

amqp gem 0.9.10 is released to rubygems.org.

This release includes one bug fix. It is 100% backwards compatible.

Change Log

Delayed Queue Operations Now More Resilient to Race Conditions

With amqp gem, code like this

1
2
3
ch.queue("", :exclusive => true).bind(x).subscribe do |meta, payload|
  # ...
end

will delay queue.bind and basic.consume operations until after the server-generated queue name is known.

In some cases (e.g. WebSocket/RabbitMQ proxies), the channel may be closed before they all complete. This results in a connection-level exception (unknown channel being used) which renders the entire connection unusable.

Starting with amqp gem 0.9.10, delayed operations have a guard that prevents them from being executed if the channel is already closed.

Michael on behalf of the Ruby RabbitMQ Clients Team

Amqp Gem 0.9.9 Is Released

TL;DR

amqp gem 0.9.9 is released to rubygems.org.

This release includes a few bug fixes and minor improvements. It is 100% backwards compatible.

Change Log

  • Large [> 128K] messages with non-ASCII characters are now framed correctly (as of amq-protocol 1.2.0).
  • Minor efficiency improvements in basic.publish serialization code.
  • Heartbeats delivery is now paused when a network failure is detected.

Michael on behalf of the Ruby RabbitMQ Clients Team

Bunny 0.9.0.pre7 Is Released

TL;DR

Bunny 0.9.0.pre7 is released to rubygems.org.

This release consists of bug fixes and (very) minor features. It is 100% backwards compatible.

Highlights

This release includes a number of bug fixes and (very) minor features plus API reference.

Change Log

Bunny::Channel#on_error

Bunny::Channel#on_error is a new method that lets you define handlers for channel errors that are caused by methods that have no responses in the protocol (basic.ack, basic.reject, and basic.nack).

This is rarely necessary but helps make sure no error goes unnoticed.

Example:

1
2
3
channel.on_error |ch, channel_close|
  puts channel_close.inspect
end

Fixed Framing of Larger Messages With Unicode Characters

Larger (over 128K) messages with non-ASCII characters are now always encoded correctly with amq-protocol 1.2.0.

Efficiency Improvements

Publishing of large messages is now done more efficiently.

Contributed by Greg Brockman.

API Reference

Bunny API reference is now up online.

Bunny::Channel#basic_publish Support For :persistent

Bunny::Channel#basic_publish now supports both :delivery_mode and :persistent options.

Bunny::Channel#nacked_set

Bunny::Channel#nacked_set is a counter-part to Bunny::Channel#unacked_set that contains basic.nack-ed (rejected) delivery tags.

Plans for 0.9.0 Final

There is still a few things we need to do before Bunny 0.9 can be declared complete:

  • Make network failure recovery configurable
  • Bring back TLS support
  • Add logging

Michael on behalf of the Ruby RabbitMQ Clients Team