Making today worse so tomorrow seems better.
Using New Relic add_method_tracer with Class methods
At Vocel we use the New Relic plugin to monitor the performance of our production Rails apps.
In addition to the built-in ActiveRecord and Controller metrics, you can define your own custom metrics. The documentation clearly shows how to add a metric to an instance method, but how do you add one to a class method?
I’m using custom metrics to differentiate between time spent in our app and time spent waiting for external components. So we can imagine that we have a class like:
Estimating Key Collisions (Birthday Problem)
Thanks to a somewhat well known statistical behavior known as the Birthday Problem, collisions of randomly generated keys are much more likely than you would expect. You can estimate how likely with some quick Ruby.
I ran into real world application of the Birthday Problem while I was building the mBlox adapter for Vocel’s SMS product. Most APIs for sending SMS give you back a randomly generated tracking ID when you submit a message. This tracking ID can then be used to report the delivery status of the message.
The mBlox API doesn’t automatically return a tracking ID, but it allows you to set one of your own. Could we get away with just randomly generating our own without checking to see if we had used the ID yet?
After some research online, I built this little method to determine the chance of having at least one collision in a set of randomly distributed keys ‘k’ out of a range of ‘n’ possible values. While calculating the exact probability for large numbers isn’t easy, it turns out estimating it is.
The real problem with the mBlox API is that the maximum value for their “BatchID” parameter is 99,999,999. That would make a big salary, but it’s not a big keyspace. For the expected trial run of 70,000 messages, the chance of at least one collision is over 99.999%.
The Blarg is Back!
Now that Merb is going to be Rails, we figured that we would overhaul the old blarg and bring it back to the Rails world. But to keep things interesting, we decided to go all Ruby 1.9.
We also moved the code over to GitHub while we were at it. So if you want to see what we’ve been up to, head over to http://github.com/gnarg/blarg and have a look.
(Note that the RSS feed is still broken, but that will hopefully be working again shortly.)
The Details
The backend is still CouchDB, so we didn’t have to sweat out the mysteries of Ruby 1.9 versus the MySQL adapter. In fact we pulled out ActiveRecord entirely, who says Rails is monolithic?
We are using Thin for the web server, which seems to be working great under 1.9. Mongrel had compilation issues, and we didn’t want to try moving our entire Passenger setup to 1.9.
We use the RedCloth, hpricot, json, and dm-validations gems and none of those gave us any trouble under 1.9.
Michael has been working hard on beefing up our CouchDB interface with DataMapper. With luck we should get a post from him shortly on that topic.
JNDI with Rails
29-JUN-09 – updated formating to work with the latest version of blarg
I like to explain the relationship between Rails and Java is that Rails makes the things I hate doing easy and Java makes the things I like doing possible.
In this mind set, when using Rails on JRuby I want to do as little configuration in Java (XML sit-ups are bad) and leverage Rails as much as possible (a few yml stretches are good). The most common configuration cross over is the database connection. This is where JNDI helps out, now both sides can use the same connection pool.
Putting your ducks in a row
For the following examples to work, you will need the follow dependencies:
- Sun’s JNDI File System Service Provider. Follow “Download JNDI 1.2.1 & More” to download File System Service Provider. You will need the fscontext and the providerutil jars both in you classpath. I would like to take this moment and say that Sun needs to get their head out of the mud and join the Maven party, instead of forcing people to navigate their cumbersome site.
- Maven will make you hate less. Manually managing the cadre of jars that Java demands will just chalk you full of spite. While Maven does not alleviate the problem, it does put a purdy bow on it
- A given, you must already have gone through the steps of setting up a JRuby runtime. Steps might be to strong of a word, basically it is unpackage and go.
Configuring Rails to create its own JNDI and Connection Pool
Now it is time to get the show on the road. The following setups will show how to startup a JNDI instance, register a Connection Pool, and then use the same Connection Pool in Rails and in a Spring
Setting up the database.yml
The latest version of activerecord-jdbc already supports using JNDI for connections. By setting additional information in database.yml, jndi_factory_initial and jndi_provider_url, a connection pool can be built and registered into JNDI. The jndi_factory_initial relates to the JNDI property java.naming.factory.initial, which boils down to the JNDI service that is going to be created. The jndi_provider_url relates to the JNDI property java.naming.provider.url, which is the URL to connect to the JNDI service. The standard setting, jndi, is going to be used as the location to store and retrieve the Connection Pool.
JRuby Service in Rails
I have two worlds that need to collide. Rails solves the decade long problem of abusive Java web stacks and Java provides mature codebase to the Rails paradigm. JRuby has brought me the spark, now if I can only get the fire burning.
The problem: I need a Spring context to startup with Rails and use the config/database.yml.
The solution: A JRuby Service.
I want to expose tons of existing Java code and libs into Rails, but do not want to deal with a segmented world. Everything should be configured and started from one place, this is were a JRuby Service helps. The JRuby runtime will automatically load a class implementing a JRuby service interface (such as org.jruby.runtime.load.BasicLibraryService) when it is packaged in a specifically named jar at a specifically named placed.
Originally I was jumping though hoops trying to call static singletons, but ended up scratching my head how to get access to the Rails runtime. After finding hints from Ola Bini, with some searching and source diving, I found the javadoc for org.jruby.runtime.load.LoadService has the key. (An aside, it would be nice if the JRuby folks published the JavaDocs, even if it changed with every release).
Except from LoadService.java JavaDoc:
bq. How to make a class that can get required by JRuby
- About
- Technology, programming, the interwebs and other topics by members of the slackworks community.
- Contributors
- All Posts
-
- Aug 05 2009 Using New Relic add_method_tracer with Class methods
- Jun 30 2009 Estimating Key Collisions (Birthday Problem)
- Jun 29 2009 The Blarg is Back!
- Jul 23 2008 JNDI with Rails
- Jul 06 2008 JRuby Service in Rails
- May 16 2008 Wildcard DNS and Rails
- Jan 30 2008 Sprint Error "911" and the "Download Domain"
- Jan 16 2008 Getting a Good View of Your Couch
- Jan 12 2008 Bring Selenium to the integration party
- Jan 12 2008 Bj Makes Attachment_fu Happy
- Jan 03 2008 Restore Finder magic to a sparsebundle directory
- Dec 18 2007 First Post