It’s an exciting time for the Rubinius project, an alternate Ruby implementation focused on concurrency and speed. The long anticipated 2.0 release arrived in early October, and the Rubinius team has been iterating quickly, already reaching 2.2.1 as of mid-November.
At New Relic, we’re always excited by new possibilities in the platforms we support, and with the Ruby agent’s 3.7.0 release we now provide full support for Rubinius! We’ve seen a few issues along the way, but the Rubinius team has quickly gotten the critical items fixed.
We’re keen for those of you on the cutting edge to try New Relic with Rubinius and tell us how it goes. If you see any problems, don’t hesitate to file a support ticket. For the up-to-date status on New Relic’s support for Rubinius, keep an eye on the New Relic on Rubinius page.
Beyond the announcement, I also wanted to share what it took to get our tests running with Rubinius. Running the Ruby agent smoothly on Rubinius was straight-forward, but did require a few changes.
rubysl and racc
The big change people first encounter with Rubinius is rooted in Rubinius’ choice to ship the Ruby standard library as a gem, called
rubysl. While MRI provides the standard library functionality without any additional gems, Rubinius needs the dependency explicitly declared.
At first this seems like an annoyance. Who doesn’t want the standard library? But it’s more about versioning than the dependency declaration. Separation as a gem allows updates to the standard library without requiring a new runtime release. More background can be found in the “What Are Gems?” section of this post from Brian Shirai.
Bottom line, add the following to your Gemfile:
gem 'rubysl', :platforms => :rbx
We found some versions of Rails had a similar issue around the
racc gem. Again, one line in your Gemfile, and you’re off and running.
Garbage Collection Metrics
Older Ruby agents worked with Rubinius < 2.x. Back on Ruby 1.8.7 and earlier, MRI didn’t provide a standard way of accessing statistics about the garbage collector. Both Ruby Enterprise Edition and Rubinius, though, provided their own implementation-specific API’s for querying their garbage collectors, and New Relic tapped into that data to give more insight into applications.
Happily, with the advent of Ruby 1.9.x, a standard library interface for garbage collection information was introduced. Being compatible with Ruby 2.0, Rubinius fully supports
GC::Profiler out of the box.
It’s unlikely to be of interest to many folks, but if you happened to tinker with Rubinius way back and queried GC metrics, changes are in your future.
Most developers shudder at the mention of ObjectSpace, and with good reason. This API gives access to any live object in your Ruby process. It’s powerful, potentially dangerous, and definitely slow outside of MRI. There’s a reason that JRuby has it turned off by default.
It turns out Rubinius’ internal implementation shares JRuby’s issues, and in particular ObjectSpace._id2ref is very slow. While we avoid ObjectSpace where possible, running on Rubinius flushed out a few corners where the Ruby agent was using it. We’ve addressed those, and the performance improvement on Rubinius was awesome.
Migrating between Ruby implementations isn’t always simple, but working with Rubinius 2.x has proven easier than we initially expected.
What’s your experience been with Rubinius and New Relic? We’d love to hear about it!