Andrew Cantino's blog



Andrew CantinoAndrew Cantino
Extreme Pairing
edit Posted by Andrew Cantino on Tuesday December 14, 2010 at 01:31PM

Given the recent interest and discussions around pair programming, I thought that now would be a good time to write up my experiences doing dual-computer, in-person pair programming with Mavenlink at Pivotal Labs. Pivotal Labs is all about pairing and every team here pairs full time. Our standard setup is to have two developers at each workstation, with two mice and keyboards. On Mavenlink, we recently upgraded our workstations and decided to keep the older model around to try out dual-computer pairing, which we’ve nicknamed "Extreme Pairing."

One commonly-expressed frustration with pair programming is that of wasted time while doing especially rote programming, research, documentation reading, or printout debugging tasks. People read documentation at different speeds, or want to try different Google searches in parallel, for example. Generally, the benefits of pair programming greatly outweigh the downsides, and we pair full-time to decrease the risk of failing to pair when it would retrospectively have been of great value due to knowledge sharing or bug prevention. However, in an effort to minimize these inefficiencies, the Mavenlink team has been exploring dual-computer pairing.

What follows is not Pivotal’s standard pairing setup. Everyone on this team has years of pair-programming experience and we have each developed our own intuition for which corners can be cut and which cannot. The following is recommended for advanced pairs only -- it can make experienced pairs more effective, but may be hazardous for newcomers to the pairing environment! We never “Extreme Pair” when conducting interviews and revert to a more traditional setup in that context.

Extreme Pairing

Each of our two pairing desks house a beefy i7 27-inch iMac and a slightly older 24-inch iMac, each with its own mouse and keyboard, and linked bidirectionally with Teleport. We sit centered around the larger iMac and use the second computer when we have separable tasks during pairing, such as research, running tests, or looking up documentation. We still do traditional pairing 90%+ of the time and focus on never falling into the traps of soloing: email checking, distractions, siloed knowledge, and untested code. Having the second computer has allowed us to split our focus when we can do so while still both maintaining understanding and ownership of everything that is going on. This is most effective and appropriate when:

  • tracking down bugs; we are both able to apply different tactics simultaneously while talking to each other. This allows us to divide and conquer, then rejoin when we’ve made progress in our understanding of the base problem.
  • looking at docs; we can both read at our own pace and synchronize afterwards.
  • the non-driving pair can support the driver by setting up the context for an experiment, running rake tasks, etc.
  • googling and researching
  • optimizing, one person can track down issues with Query Reviewer or Rack Bug while the other can identify the underlying problems in the source.
  • browser testing and CSS tweaking in multiple browsers. In particular, we have found running windows in Parallels on the non-primary machine a boon to speed and productivity on the primary machine.
  • capturing stories in Pivotal Tracker

More generally, any time a task requires focus on two different places at once, we split it up and assist each other. I think of this as synchronization in multi-threaded code - we split and rejoin on separable sub tasks, while both continuing to perform traditional pair programming when viewed from the scope of a story. We never work on separate stories and tasks that last longer then a minute or so. Smoothly moving from traditional pair programming to separately googling, debugging, or CSS tweaking keeps us agile and efficient while maintaining all of the very-real benefits that we find to exist with traditional pair programming,

Does this sound like fun? Mavenlink and Pivotal Labs are hiring!

Andrew CantinoAndrew Cantino
Look sharp, the build just went red (on Campfire)!
edit Posted by Andrew Cantino on Wednesday March 03, 2010 at 01:55PM

In order to post to our Campfire chat when the CI goes red, we threw the following script in script/campfire_post:

#!/usr/bin/env ruby
require 'rubygems'
require 'net/http'
require 'uri'
require 'json'

url = URI.parse('http://SUBDOMAIN.campfirenow.com/room/ROOM_ID/speak.json')
req = Net::HTTP::Post.new(url.path)
req.basic_auth 'API_KEY', 'X' # leave the X
req.body = JSON.dump({ :message => { :body => ARGV.first }})
req.content_type = 'application/json'
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
case res
  when Net::HTTPSuccess, Net::HTTPRedirection
    # OK
  else
    res.error!
end

And then in cruise.rake:

desc "The task that cruisecontrol.rb runs"
task :cruise do
  begin
    rake "spec"
    # etc
    # etc
  rescue
    exclaim = ["Oh goodness, t", "OMG t", "Look sharp, t", "Attention everyone! T", "Ohnoes! T"][rand * 5]
    system "ruby script/campfire_post '#{exclaim}he build just went red!'"
    raise
  end
end

And it's even cheeky!

Andrew CantinoAndrew Cantino
Standup 2/11/2010: Sass with Jasmine
edit Posted by Andrew Cantino on Thursday February 11, 2010 at 09:24AM

Interesting Things

  • If you are testing with jasmine, it's a good idea to include your CSS files in the test runner. This prevents, for example, issues where you've hidden an element in the CSS and expect it to be visible in your JavaScript. If you are using Sass, then you should regenerate your CSS from the Sass before running the jasmine tests. The current version of haml-edge updates the sass command-line tool with an update command. On one of our client projects, we added the following to our jasmine_config.rb file:
  def update_sass
    puts "Updating sass files..."
    rails_root = File.expand_path(File.dirname(__FILE__) + "/../../../")
    sass_path = "#{rails_root}/vendor/bundler_gems/ruby/1.8/gems/haml-edge-2.*/bin/sass"
    puts `#{sass_path} --update #{rails_root}/app/stylesheets:#{rails_root}/public/stylesheets/generated`
    puts "done."
  end

  alias_method :old_start, :start
  def start(*args)
    update_sass
    old_start(*args)
  end

  alias_method :old_start_server, :start_server
  def start_server(*args)
    update_sass
    old_start_server *args
  end

Andrew CantinoAndrew Cantino
Standup 2/10/2010: Calling all railsplugins.org
edit Posted by Andrew Cantino on Wednesday February 10, 2010 at 09:10AM

Interesting Things

  • When testing with jasmine and using jQuery live events, be sure to stop the events between tests. If you don't, they can cross tests and cause confusing results.
  • RailsPlugins.org is asking that all Rails plugin developers register their plugins on the site. This will both help determine the set of plugins that are ready for Rails 3, and also provide a comprehensive directory of plugins.

Andrew CantinoAndrew Cantino
Standup 2/9/2010: Bundler 0.9.x, Amazon S3 versioning, and Safari console debug questions
edit Posted by Andrew Cantino on Tuesday February 09, 2010 at 09:26AM

Interesting Things

  • Bundler is now at version 0.9.x. The 0.8 to 0.9 release included many improvements and large internal changes. Everyone should probably upgrade, but be aware that this may be disruptive to your project, as the bundle command has changed names. You should be aware of this before upgrading. Yehuda has posted a comprehensive blog post about using Bundler that is worth reading. Since Bundler is in beta, it will probably keep changing.
  • Amazon has released a beta versioning feature for S3 that allows you to keep a full history of changes to your S3 objects. This looks useful.
  • There is some question about what state of a DOM node is shown in the Safari console when console.debug is called. Is it the state of the DOM node from exactly when the call was made, or is it some later state due to Safari asynchronously displaying the console messages? We are going to do some research and will update at a future standup.

Edit:

It sounds like the Safari issue occurs when logging a reference. Mentioned workarounds for the Safari issue include:

  • explicitly logging the variables that you are interested in; i.e., console.log(obj.a, obj.b)
  • using the debugger
  • transforming the object to JSON
  • using console.dir
  • logging a string

Andrew CantinoAndrew Cantino
Standup 2/8/2010: Potential Geminstaller issues
edit Posted by Andrew Cantino on Monday February 08, 2010 at 10:23AM

Interesting Things

A project reported that GemInstaller failed when installing Rails 2.2.2, because it attempted to list the remote Rails 3.0.beta gem. There's a bug open and awaiting more info, but since this is not reproducible on RubyGems 1.3.5, it may be due to an old RubyGems version not handling prerelease gems properly.

The GemInstaller author heartily recommends that you switch to Bundler anyway