RadRails on linux with JRockit

Saturday, February 25

Lately, I’ve been using RadRails for Rails development on my laptop (ubuntu linux), and for some reason I find it painfully slow. I decided to google “RadRails performance” and stumbled upon JRockit, an optimized JVM for multiple platforms.

I downloaded JRockit from the BEA site and followed the installation instructions for linux to get it running. So, here’s the quick summary of how I put RadRails on JRockit.

Download the JRockit installer, put it somewhere, and make it executable:

$ chmod +x jrockit-R26.0.0-jdk1.5.0_04-linux-ia32.bin

Now you can run the installer in console mode and it will walk you through the rest of the process. I used the defaults for everthing and just Next’d my way through.

$ ./jrockit-R26.0.0-jdk1.5.0_04-linux-ia32.bin -mode=console

With JRockit installed, getting RadRails to use it is a simple matter of appending the -vm argument when launching it. You can do this directly from the command line, or if you’ve created an icon launcher, you can edit its command:

$ ./radrails -vm ~/jrockit-R26.0.0-jdk1.5.0_04/bin/java

The speed improvement is noticeable, but it’s nothing earth shattering. Still, it saves me a few seconds when I open files—before JRockit it would take ~3-5 seconds to open a file. Now it’s down to about one second which is at least bearable. I’m really starting the feel the hurt of not having TextMate on linux. I think it’s time to bite the bullet and pick up one of those new MacBooks. Now, if I could only convince my wife…

UPDATE: after several crashes and a decision to revert to the default (Sun) JVM, I found Christian Pelczarski’s article on the subject in which he claims “[the] new Sun JVM seems a bit faster than JRockit.” (Granted, his article pertains to Windows, but I figured I’d try it anyways.) I’ve been running RadRails with it for about an hour now; performance is about the same as with JRockit 5, but it’s certainly more stable.

DemoCamp tonight

Monday, February 20

The next installment of DemoCamp is going down tonight at the Tucows offices in Toronto. The brainchild of David Crow, DemoCamp is a monthly gathering for developers to show off what they’ve been working on and talk shop with other geeks. Head on over to the wiki page to see what’s on the agenda.

I’ve been working with my friend Cloves on a Rails app that we were hoping to demo tonight, but alas, software is harder to ship than I often realize. We made a mad dash on the weekend, slashing features and tying up loose ends, so it looks like we’ll have version 1.0 out the door this week (famous last words, right?) and will be able to demo it at the next camp.

I’m looking forward to meeting other Rails developers tonight and putting out the word about something Cloves and I have been cooking up: sore

Migrations demystified

Thursday, February 16

Migrations in Rails allow you to incrementally change your database schema using pure Ruby by generating auto-numbered class files that can be checked into your version control system and easily deployed with a rake task. Perhaps the best part about this approach is that it’s database agnostic: it doesn’t matter whether you’re using mysql, or postgresql, or whatever—as long as the adapter supports migrations, you don’t need to worry about writing database specific sql statements anymore.

Prior to migrations, I would usually create sql files containing any necessary transformations and keep them under version control. This approach works for a while, and if you’re the only one working on the project you may not notice an immediate need for migrations because your schema is easy to manage. But trust me, as soon as you begin working with others, or if you have to deploy database changes in the production environment, you’ll be glad you took the time to learn about migrations.

Enough talk. Let’s dig in by creating our first migration. From your Rails root, type

./script/generate migration Genesis

This will create a new file in db/migrate called 001_genesis.rb. (Note that the numeric prefix is automatic; since this is our first migration, it is numbered as such). This file has a single class that extends ActiveRecord::Migration containing two empty methods: up and down. For each migration, you define instructions for updating in the up method, and use the down method to roll back any changes. So, if you were to, say, create a new table in the up method, you could drop the table in the down method thereby reversing your changes. Rails provides a number of methods that you use to create and drop tables, add and remove columns, rename columns, and more (see the AR::ConnectionAdapters::SchemaStatements documentation for the complete list of them).

Let’s get to work on on the up method by creating a new table. We’ll let the code speak for itself:


class Genesis < ActiveRecord::Migration
  def self.up
    create_table :messages do |t|
      t.column :name, :string
      t.column :body, :text
    end
  end
  ...
end

As you can see, `create_table` takes a table name and a block. Inside the block, we pass a fieldname and a format type to the column method. That’s all there is to it! If you were to run `rake migrate` right now, this simple migration would create a new table called messages with the columns id, name, and body. You might have noticed that we didn’t even bother creating the ubiquitous auto_increment id column. That’s because we don’t need to. If it’s omitted, Rails is smart enough to go ahead and add it for us, saving us the typing.

Now, creating tables is all right and good if you’re starting from scratch. But if this is an existing project I bet most of us will have already created a db/create.sql file that houses a ddl full of tables and maybe even data to be initialized. Ideally, we’d like our first migration to set all this up for us, but that might be a lot of work depending on the size our our schema. Wouldn’t it be nice to easily generate a our first set of transformations from our existing schema without having to type them all in by hand?

Rake to the rescue. Rails includes a rake task called `db_schema_dump` that will generate a programatic representation of your existing database structure in just the flavor we need for a migration. Go ahead and give it a try:

$ rake db_schema_dump

After rake is all finished, you should find a fresh new file in your db/ directory called schema.rb. Open it up and have a look. See? There are all the calls to create_table already done for you. All you have to do is copy everything inside the block given to “ActiveRecord::Schema.define” into the up method of your migration and you’re ready to rock.

With your initial schema defined in the up method, it’s time to give it a full test. But before we do that, we should probably put something in the down method. Given that this is our first migration we can’t really roll back to anything (other than an empty database, I guess), so you might call this migration irreversible. Well, wouldn’t you know it—there’s a special exception you can raise for rare situations such as this called (you guessed it) IrreversibleMigration. Our down method, then, would look like this:


def self.down
  raise IrreversibleMigration
end

Let’s try out our migration. Drop and recreate your development database so that we have an empty canvas to start with, and then run $ rake migrate. After a few seconds of crunching, rake will unceremoniously complete its task and leave you with a blinking cursor at the command prompt. But if all went according to plan, your database should be chalk full of tables again. Go check it out.

Sometimes our schema definitions initialize data for us. You’ll be happy to know that adding data with migrations is easy and practical. Here’s a quick example:


def self.up
  create_table :messages do |t|
    t.column :name, :string
    t.column :body, :text
  end

  Message.create :name => 'Test',
                 :body => 'Drank my sleep from a can'
end

Notice that we’re using the Message model to create our data (Message.create). So, the Model’s rules (like validations, callbacks, etc.) are always enforced. Since Rails is of the opinion that all access to the database should be through the Model, this is a good thing. You wouldn’t want to execute a sql file that added invalid data to your database, would you? Of course not.

Let’s take a typical example of a User model that uses the before_create callback to hash the password. If I were to add a new user via sql, how would I go about hashing their password? (No, putting the hashed string directly in the sql isn’t a good idea—what if you change the hash’s salt?) Initializing data using the Model means that the callbacks will fire, and the password will get hashed as expected. Nice, huh?

Switching to Markdown

Wednesday, February 08

Ever since I began to appreciate the usefullness of a text-to-html conversion filter, I’ve been a Textile man. This is not so much due to preference as it is to convenience; Textile is supported in most of applications I use on a daily basis (Basecamp, Backpack, Typo, etc.), most blogging tools support it, and adding it to applications is made easy by libraries for nearly every language.

Enter: Markdown, a worthly alternative to Textile. The product of John Gruber, it is evangelised by some and feared by others. I am of the latter camp; why would I want to try Markdown when I already know Textile?

It is the fact that I always build support for Markdown into my applications but never use it (why do I implement features I never use?) that I have decided to switch. I mean, I already know Textile. I’ve even hacked a Firefox extension that adds a Textile context-menu to textareas, on whose download page I extol the virtues and prevalance of Textile, only making a passing reference to Markdown, its evil twin. It occurs to me that it’s akin to the never-ending debate over Vim vs. Emacs confession: I am a Vim man and have never tried Emacs.

I’ll write more about this later, but I am hereby converting to Markdown. On the next episode of trying-new-things: dvorak—qwerty’s successor.

Backpack API to the rescue

Wednesday, February 08

I was just mucking about in Backpack, and noticed that I had this one rogue and title-less list that I couldn’t remove. Normally, the trashcan to delete a list peeks out when you hover over the title, but when there’s no title, there’s no trashcan.

I dug through html source to find ‘destroy list’ call, thinking I could just paste that URL into my browser and execute it manually. But no dice (I think the destroy action must enforce xhr (AJAX) requests). So I had to find another way; I didn’t want to have to email 37signals and ask them to delete a stupid list for me. Then it hit me: the Backpack API!

After doing a small celebratory dance, and armed with my API key, the URL from the html source, and the oh-so-simple instructions, I fired up curl and got rid of my list with a one liner.

Yet another fine example of yak shaving for you.