Ruby Binding (FFI)

Purpose

The C-extension based Ruby bindings from the 0mq project only work with Ruby runtimes that support the full C extension API. At this time the gem works with MRI 1.8.x, 1.9.x and Rubinius master. The JRuby project has best-effort C extension support so the official zmq gem may not run well on that platform.

This gem adds FFI bindings so that any ruby runtime supporting the latest FFI API will work. At this time the minimum versions that will work with the FFI bindings are MRI 1.9.3-p194, JRuby 1.6 and Rubinius (commit 9cf0fd29).

Should I Use FFI Bindings or the C Extension?

This project has a lot more activity than the C extension. I (am biased and) recommend everyone use this project. This project provides the most flexibility since it will work well with every active Ruby runtime (MRI, JRuby and Rubinius). Why limit yourself unnecessarily?

Performance Notes

Using Ruby-FFI adds a little bit of overhead to C function calls since the binding itself is written in Ruby with some C or Java helpers behind the scenes. I have made every effort to reduce this overhead to a minimum.

For example, the send and recv method calls return a Message class**. This class contains an FFI::Struct which mimics the zmq_msg_t struct. It provides methods for returning an FFI::MemoryPointer pointing to the data buffer as well as a call to return the size of that buffer. Due to this wrapping, no copying of the zmq_msg_t is performed.

To process the data buffer, I recommend subclassing Message and lazily copy data from the buffer as necessary. Reference the FFI Wiki for information on how to work with FFI::MemoryPointer and FFI::Struct.

I ran a battery of tests on my desktop Mac. Your timings will definitely vary but the relative performance of each runtime should be roughly the same.

I have removed the results of the latency test because they were about 2 years old (done in 2010). I'm preparing to do a new set of comparisons and will post the table data here when I have completed the work.

Source Code

http://github.com/chuckremes/ffi-rzmq

Build and installation

Install the latest ØMQ release from here:

http://www.zeromq.org/area:download

There are two options for installing the gem.

1. Install from rubygems.org via gem install.

% gem install ffi-rzmq

2. Install the latest master source from github.

$ git clone http://github.com/chuckremes/ffi-rzmq.git
$ cd ffi-rzmq
$ gem build ffi-rzmq.gemspec
$ gem install ffi-rzmq-*.gem

You may have to run the last command with sudo if you do not have permission to install to a protected system directory.

Windows

The steps for installing the gem are exactly the same. Building and installing the 0mq library may take a few extra steps. Be sure to reference the instructions on the 0mq download page.

Documentation

The gem includes some very basic rdoc. While the docs are rather sparse at the moment, be sure to check the examples gem directory. Also, the 0mq C API documentation is a good reference. These ruby bindings mimic that API exactly though a few extra sugarings have been tossed in.

Also, be sure to read the ZeroMQ User Guide. The text is growing almost daily with new examples and clearer explanations.

Learn by Example

The learn ruby ZeroMQ project uses ffi-rzmq , providing what is currently the largest set of examples using the ffi-rzmq gem.
http://github.com/andrewvc/learn-ruby-zeromq

Test Suite

Run the examples. Requires rspec, rake and bones to be installed.

% rake spec

Bug Reporting

If you encounter problems please fill a bug report at:

http://github.com/chuckremes/ffi-rzmq/issues

or write an e-mail to:

git AT chuckremes DOT com

Mailing List

Discussions about this language binding take place on the general zeromq-dev list.