Wednesday, September 21, 2011

Shrinking the stock Ubuntu AMIs for EC2

Ubuntu provides official Amazon Machine Images (AMIs) for use on the EC2 cloud. By default you get a root filesystem of 8GB. If you're keeping all your application data on a separate partition (often a wise idea), the 8GB root partition may be more than you need.

You can shrink the root volume by stopping the instance, detaching the volume, attaching it to another running instance, and rsyncing its contents into a fresh, smaller volume. There are detailed instructions on the Ubuntu forums. However, there is one extra critical step that's required on at least the newest Ubuntu images (Natty) that I haven't seen documented anywhere.

By default, Ubuntu locates the root filesystem by volume label, not by device name. Take a look in /etc/fstab and you'll see which label it's looking for (currently "uec-rootfs"). So after you copy into the new volume, do

e2label /dev/xvdg uec-rootfs
(assuming /dev/xvdg is your new volume).

Thursday, September 15, 2011

Unit Testing Javascript with the Rails Asset Pipeline

The Rails 3.1 Asset Pipeline offers new possibilities for unit testing your Javascript/CoffeeScript assets. By making it easy to preprocess, bundle, and serve your code, Rails leaves you with very little glue to write.
Here's one strategy I've been using that offers several benefits that were previously hard to combine:
  • write both code and tests in any combination of pre-processable languages, relying on Sprockets and the asset pipeline to automatically find and compile everything.
  • tests can execute in the browser with a nice graphical UI.
  • the exact same tests can execute from the shell with no browser. I'm using therubyracer.
I have an "app/assets/javascripts/test.js" manifest file like this:
And I have an "app/assets/javascripts/test" directory that contains Jasmine specs. All the tests defined in there will automatically be included.
To run in the browser, you just need <script type="text/javascript" src="/assets/test"></script>. But for maximum debugability, put it into an Erb template and use <%= javascript_include_tag "test" %>. That way you can call it with &debug_assets=1 to get useful filenames and line numbers in your stack traces.

To run from the shell, we can grab our source directly out of the asset pipeline and stick it into a Javascript execution environment:
Of course there are still a few more details to take care of to trigger the tests, produce nice console output, and set Rake's exit status. Here is a full example config.

Wednesday, September 14, 2011

Keeping a Sproutcore 2.0 App Fast

Our application makes heavy use of the excellent open-source Sproutcore 2.0 library. One thing I've discovered about Sproutcore is that if you want your application to be as responsive as possible, there are a few tweaks you can make to keep re-rendering to a minimum.

One example is related to Sproutcore's #if and #unless template helpers. They are simple, clean, and nice to use. But as the amount of complex content that you're wrapping inside them grows, they can get expensive and cause perceptible delays as they rerender. Instead of re-rendering complex content, it's much cheaper to just hide it when you don't want it to be visible.

Here is an implementation of the helpers #showIf and #showUnless. You can use them like #if and #unless, but instead of rerendering their content, they just show or hide it with the CSS display:none property. (Except these don't offer {{else}} — you need to use a #showIf & #showUnless together for the same effect.) If you're wondering why my Javascript is so bizarre, it's because it's CoffeeScript. You can easily compile this to Javascript without installing anything by heading over to the CoffeeScript site, clicking "Try CoffeeScript", and pasting in the above code.