a work on process

Book Review: Ruby on Rails Web Mashup Projects

29 July 2008 (4:16 pm)

By James Stewart
Filed under: Notes
Tagged:

Providing a whistlestop tour through building a range of Ruby on Rails applications on the back of other services, Ruby on Rails Web Mashup Projects is aimed at those who are already comfortable building rails applications and want some sense of how they can be enhanced using a variety of other visualisation, data and processing providers.

Aside: The term ‘mashup’ is one of those tech terms that’s almost impossible to pin down. I should note that the way it used in this book (seemingly any application that draws on a third-party services) is not a way I’d choose to use it, but I’d rather focus on the book itself than on titling semantics.

The book hits all the usual suspects—google maps, flickr, technorati, wikipedia—and also covers the basics of building a facebook application, using paypal for payment processing, and sending faxes and SMS messages through a third party gateway. For those who want a quick overview of all of those options it’ll give you enough to get started, though as a result of the pace only the very basics of each service is covered and anyone wanting to build a sophisticated app will have quite a bit of work in front of them learning the nuances of their chosen service providers.

Along with providing little detail of each service, the book suffers from not really digging into a number of topics that would make it a much more useful companion. Big challenges when building applications dependent on other peoples’ servers include effective testing, caching, surviving third-party service outages, and good ways of integrating your interface code into your application.

Lip service is paid to the need to be prepared for a third-party service outage, but no examples of how to survive are offered. It wouldn’t have been hard to illustrate ways of falling back to local databases or to secondary services, but none is offered. There’s no mention of writing tests, so no opportunity to offer ways to use mocks to test the local code or to discuss how you might automate your testing of the integration itself, and caching is similarly overlooked except in the case of amazon e-commerce services where it is used to preserve historical data that amazon doesn’t make accessible.

The absence of testing really shows through in some of the code offered. Much of the code demonstrated in the book is overly complex and procedural, with little in the way of modular, reusable components. Similarly there’s little by way of discussion of where such code fits into your rails application, with some classes that are clearly models (albeit non-ActiveRecord models) dropped into the lib folder, and numerous very fat controllers.

Rather than covering seven separate projects, this box would have been much stronger had it focussed on two or three, but worked through them in significantly more detail. Possibly there wouldn’t have been a chance to touch on as many services, but by building up one of the more diverse systems like the ticketing application in detail, covering failover, testing, clean integration with a rails app, and other such topics this could have been a much richer book with appeal for a far wider range of developers. As is, it’s worth skimming through if you’re looking for advice on sending faxes or SMS, but won’t help much with the real challenges of building a robust application that’s dependent on third-party services.

Disclaimer: I was sent a copy of this book for review by the publisher. You can find it at packt, amazon US, amazon UK and all sorts of other places.

Recommend this post:

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

 

links for 2008-07-26

26 July 2008 (4:31 am)

By James Stewart
Filed under: Notes
Tagged:

Recommend this post:

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

 

Deploying a Drupal Site with Capistrano 2

23 July 2008 (10:07 am)

By James Stewart
Filed under: Notes, Snippets
Tagged: , , , ,

A little over a year ago I wrote up some instructions for deploying drupal sites using capistrano. It’s proved a popular entry, still getting a good bit of traffic, but in the time since I wrote it Capistrano 2 has joined us and my techniques have moved on, so it seemed high time I updated the instructions with some new ones.

As before, I’m going to presume that anyone reading this already has capistrano installed and has shell access to their server. If you need help with the former, I’d recommend stopping by the Capistrano website, and for the latter you should probably talk to your hosting company.

My approach is to keep each site’s assets (modules, themes, etc) within that site’s folder, and then store each site in version control (git or subversion). In common with capistrano-based rails deployments, I then have the site’s files and images stored in a shared folder and symlinked into the site, so that they can be preserved between deployments.

To get started go into the folder for the site you want to be able to deploy (eg. /path/to/drupal/sites/mysite.com) and type at the command line:

mkdir config
capify .

That will create the basic files for deployment, which you will then need to edit with your configuration details. I start by opening the file config/deploy.rb and deleting everything in it, so as to start with a blank slate. I then put in some overrides to capistrano’s default deployment methods so that they work better with drupal:

set :asset_folders, %W(images files)
 
namespace :deploy do
  desc "Link the asset folders from the shared folder into our site"
  task :finalize_update, :except => { :no_release => true } do
    logger.info 'finalizing update with custom method'
    run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
 
    asset_folders.each do |asset|
      run "rm -rf #{release_path}/#{asset}"
      run "ln -nfs #{shared_path}/#{asset} #{release_path}/#{asset}"
    end
  end
 
  desc "Set up the expected application directory structure on all boxes"
  task :setup, :except => { :no_release => true } do
    run <<-CMD
      umask 02 &&
      mkdir -p #{deploy_to} #{releases_path} #{shared_path}
    CMD
    asset_folders.each do |asset|
      run "mkdir #{shared_path}/#{asset}"
    end
  end
 
  task :set_permissions, :except => { :no_release => true } do
    # do nothing
  end
 
  task :restart do
   # do nothing 
  end
end

You then need to set some basic configuration, so also in deploy.rb place:

set :deploy_to, '/path/to/your/drupal/sites'
 
# Make sure this is the domain name of your app as it is 
# what your sites folder will be named
set :site_name, 'staging.scodigo.com'
role :web, "your.server.com"
set :current_path, "#{deploy_to}/#{site_name}"
set :shared_path, "#{deploy_to}/shared/#{site_name}"
set :repository, "svn://your.svn.com/path/to/repos/trunk"

With that in place you’re all ready to go. But there was an extra step I decided to add this time around. Since I am frequently setting up new staging/test sites and often need to upgrade them to new versions of drupal, I wanted to be able to install and update the drupal files using capistrano.

To do that, I wrote a recipe that will grab the tarball for a given release, unpack it and install it, without wiping out an existing sites folder. To add that you will need to put the following code into your deploy.rb file:

namespace :drupal do
  desc <<-DESC
  Grab the specified version of drupal and install it
 
  This presumes that the variables drupal_version and drupal_path have been set
  DESC
 
  task :install do
    run "cd #{shared_path} && curl -O http://ftp.drupal.org/files/projects/drupal-#{drupal_version}.tar.gz"
    run "cd #{shared_path} && tar xzvf drupal-#{drupal_version}.tar.gz"
    run "rm -rf #{shared_path}/drupal-#{drupal_version}/sites"
    run "cd #{drupal_path} && rm -rf !(sites)"
    run "mv #{shared_path}/drupal-#{drupal_version}/* #{drupal_path}"
    run "mv #{shared_path}/drupal-#{drupal_version}/.htaccess #{drupal_path}/.htaccess"
    run "rm -rf #{shared_path}/drupal-#{drupal_version}"
  end
end
 
after "deploy:setup", "drupal:install"
set :drupal_path, File.join(deploy_to, '../')
set :drupal_version, "5.8" # Or whatever version you want to install

(You can download a copy of the combined deploy.rb file here or view it as a pastie here)

Now, to set up your drupal site you just need to change directory to your site and type and command line:

cap deploy:setup

and to deploy a new version:

cap deploy

In practice, I tend to use these techniques in combination with the Capistrano Multistage extension, so that I can deploy a site to a staging server first, and then a production server. I’d highly recommend that approach, but for now will leave it as an exercise for the reader.

Please note that this technique is also designed to support a multi-site drupal set up, but hasn’t been extensively tested in that context. It should work, but no guarantees!

Recommend this post:

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

 

It’s always fascinating to see how applying good practice in one area can lead to unforeseen benefits. The article on version control with subversion in the latest issue of A List Apart is a fine example of just that. Not only is the use of version control a good way to manage your own projects, it’s a vital enabler for significant shifts in working practices and management styles.

Those of us who’ve been building software for a while and keep tabs on best practice in that arena are unlikely to see version control as anything new—CVS has been around since the 80s, after all—but it’s arguably only now really coming into its own as we see social practices, work practices and coding practices coming together. And of course we’re finally starting to see promising mac subversion clients, which has to help.

On a related note, John Gruber noted a couple of days ago:

It strikes me as an odd coincidence that two serious Subversion clients would debut at a time when many developers are starting to switch away from Subversion to distributed revision control systems such as Git and Mercurial.

You could argue that it isn’t really a coincidence at all. Perhaps the fact that technologists have found a superior model for managing versions, and matured it to a point where many of us are starting to use Git is a consequence of really getting to grips with what tools like subversion allow. We’ve become good enough at communicating the features and flaws of one generation of tools that we can both provide friendly tools, and simultaneously witness a more widespread migration to their progeny?

Recommend this post:

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]