Wednesday, July 2, 2008

Contributing to Rails is easier than you think

Rails_2At OtherInbox we love open source and are looking for ways to share some of our labors with the community. Today I came across a great opportunity to contribute something to Ruby-on-Rails core development. I'm posting it here so everyone can see how easy it is to contribute.

I was building a JSON API to enable some new awesome features we're working on. Following the JSON request specification, I had the client setting its MIME type to "application/jsonrequest". But this was not causing Rails to recognize the request as JSON and thus the request body was not properly parsed. After doing some digging, I realized that Rails only looks for MIME type "application/json".

Fortunately, MIME type processing is implemented really humanely in Rails, so I whipped up a little patch that adds "application/jsonrequest" as a synonym for the JSON MIME type. First I wrote a test to prove that this was a problem. Once I had a failing test, I added the MIME type, and got my test passing. I followed the git patch instructions on lighthouse, then jumped into IRC #rails-contrib to garner support for it.

I happened to see that Rick Olson, the author of the existing JSON parsing code, was in the chat, so I pinged him with the lighthouse ticket. He tested it and applied it, and now our one line of code is a part of Rails!

Hopefully this will save some future JSON implementer a bit of pain.

Cross-posted from the OtherInbox blog

Labels: ,

Tuesday, June 10, 2008

Speaking at Lone Star Ruby Conference

I will be speaking at the Lone Star Ruby Conference in September about how we use Ruby to deploy, monitor, and manage a cluster of servers running in the Amazon Web Services virtual cloud.   Below is a summary of what I'll be talking about.

In OtherInbox, almost every system administration task imaginable is carried out using Ruby, meaning we as developers can enjoy all of Ruby's expressive benefits and spend less time scripting the shell, writing cron tasks, or using other languages. Because we make fewer context switches from thinking in Ruby to thinking in other languages, we also reap a big productivity benefit.

Using Ruby throughout our cloud also means that porting the application to run in different production environments is a trivial task, because Ruby is the glue connecting the Ruby components together, thus all we require is a Ruby interpreter to deploy.

Two key Ruby technologies have matured in the previous 18 months which make it ideal for almost every layer of managing a cluster of servers:
  • god.rb allows fine-grained process monitoring and daemon control (a la monit)
  • rufus-scheduler enables Ruby-based scheduling (replacing cron, and providing a great facility for running daemons that must be executed on a recurring basis)
When combined with these Ruby workhorses, developers today can spend much more of their time writing Ruby code, and less time struggling with the vagaries of their production environment:The talk will also include a discussion of using several different AWS gems to make cloud computing simple, by illustrating the use of Amazon's S3 and SQS services to distribute asychnronous work and handle communication between servers.

(cross-posted from the OtherInbox blog)

Labels: , , , , ,

Friday, June 6, 2008

random_data v1.3.1 released

random_data v1.3.1 is out.  Courtesy of stalwart contributor Hugh Sasse, this release includes more firstnames, and two new methods: Random.firstname_male and Random.firstname_female

Install it via:
sudo gem install random_data
or get it manually.

Labels: ,

Monday, June 2, 2008

RailsConf 2008 Recap

I wrote up a few articles on the OtherInbox blog about my experiences at RailsConf 2008:
The best blow-by-blow coverage so far is from Drew Blas.  Of the ones I attended or heard the best feedback about, I most strongly recommend looking at the slides for these: 

Labels: , ,

Wednesday, May 28, 2008

See you at Railsconf 2008

I'll be leading two Birds of a Feather sessions at RailsConf 2008 that I hope everyone will attend (or flock to):
I was also invited to sign copies of the book Advanced Rails Recipes (to which I contributed a couple of recipes) at Powell's books in Portland on May 30th at 12:30 pm.  Hope to see you there!

I'll be there with the full OtherInbox contingent, so if you're looking for an awesome startup to join, come and track us down.

Labels:

Sunday, May 25, 2008

random_data v1.3.0 released

random_data is a testing and seed data gem I wrote a few years back to help get Ruby projects up and running with semi-realistic fake data (the faker gem provides similar functionality).

I just released version 1.3.0 which includes a bunch of RDoc enhancements as well as some new features contributed by the tireless (and patient!) Hugh Sasse:
  • Added RandomData::Grammar, which lets you create simple random sentences from a grammar supplied as a hash, like so:
    Random::grammatical_construct({:story => [:man, " bites ", :dog], :man => { :bob => "Bob"}, :dog => {:a =>"Rex", :b =>"Rover"}}, :story)
    ==> "Bob bites Rex"
  • Added Random.bit and Random.bits
  • Added Random.uk_post_code
  • Bug fix: zipcodes should strings, not integers
Thanks Hugh!  Open source is awesome!

Labels: ,

Using Ruby's Autoload Method To Configure Your App Just-in-Time

Reading The Ruby Programming Language was a great experience — like revisiting a country I thought I knew intimately, but with expert tour guides who showed me whole new landscapes. It's also a good primer on what's changing in Ruby 1.9.

One of my favorite discoveries was Ruby's autoload method. Using autoload, you can associate a constant with a filename to be loaded the first time that constant is referenced, like so:
autoload :BCrypt, 'bcrypt'
autoload :Digest, 'digest/sha2'
The first time the interpreter encounters the constant BCrypt, it will load the file 'bcrypt' from Ruby's current load path, which it assumes will contain the definition of that constant. (Note that autoload takes the name of the constant, in symbol form, not the constant itself).

Here's an example of how useful it can be. OtherInbox uses beanstalkd in a few places where we haven't yet migrated to SQS. I was loading the beanstalk client with a Rails initializer, 'config/initializers/beanstalk.rb':
require 'beanstalk-client'
BEANSTALK = Beanstalk::Pool.new(['localhost:11300'])
Making this initial connection on our production server takes five seconds or more each time I restarted the app or dropped into the console. That doesn't sound like much but when you're doing that a few times a day, it starts to add up. So I moved the beanstalk code out of the initializer and into 'lib/etc/load_beanstalk.rb'. I placed all of my autoloads in a single initializer, 'config/initializers/autoload.rb'. For beanstalk, the statement is:
autoload :BEANSTALK, 'etc/load_beanstalk'
Now, the app starts more quickly, and even better, this library doesn't get loaded into memory by parts of the app that don't need it.

Labels: ,