Archive for the ‘pair programming’ Category

What’s a pomodoro?

Friday, August 20th, 2010

At eden, we often use the Pomodoro Technique™ to manage our time effectively. What exactly is a pomodoro? You could find out on the Dizionario di Italiano but i’ll give you a clue: it’s a tomato.

Share photos on twitter with Twitpic

A tomato?! How does a tomato help us manage time and increase our productivity? Well when we talk about pomodoros, we’re actually talking about a 25-minute block of time followed by a 5-minute break to reflect and assess how we’re doing and what we will do in the next 25 minutes. After four of these we take a longer break. If we’re really serious about the technique, we aim to do 12 pomodoros in a day.

This is the Pomodoro Technique created by Francesco Cirillo in 1992. It is called Pomodoro because Francesco used one of those kitchen timers shaped like a tomato.

These are the five simple steps of the Pomodoro Technique:

  1. Choose a task to be accomplished
  2. Set the Pomodoro to 25 minutes (the Pomodoro is the timer)
  3. Work on the task until the Pomodoro rings, then put a check on your sheet of paper
  4. Take a short break (5 minutes is OK)
  5. Every 4 Pomodoros take a longer break

We don’t actually use a kitchen timer (though i think it would be cool to have some!) but we use software tools instead. We use Apple’s Pomodoro timer which has Growl integration and keeps track of tasks and interruptions. When pairing remotely we use http://tomatoi.st/ which enables both people to see the time as it counts down.

At eden, pomodoro time is highly respected in terms of not interrupting unless it is really urgent. It’s very easy to say, “We’re on a pomodoro” and people know that you’ll talk to them in your next break.

We find that the Pomodoro Technique increases our focus, keeps us on track with what we’re doing, and keeps us in control of our time, rather than time controlling us. For ideas and resources, visit PomodoroTechnique.com.

Using Cucumber to test concurrency issues

Thursday, August 12th, 2010

Recently i encountered a concurrency problem of the type where there is a queue of things to do, and users press a button to be automatically assigned the next item in the queue. The bug report was that two users could get assigned the same item.

My pair programmer and i tried to reproduce the problem using two computers, but we couldn’t. We were only running one Rails instance, but we know that in the production environment there are multiple load-balanced servers pointing to one database, so we had an inkling that we’d be able to produce it using multi-threading.

To give it a test, we wrote a Rake task which we ran in two terminal windows to mimic the simultaneous access. The Rake task looked something like this:

require File.join(File.dirname(__FILE__), '..', '..', 'config', 'environment.rb')
namespace :test do
  task :take_next_for, :login do |t, args|
    user = User.find_by_login(args[:login])
    user.take_next_item
    puts user.item.inspect
  end
end

This is easily called by running:

rake test:take_next_for['ann']

We ran it for two users simultaneously and inspected the output. Sure enough they were being assigned the same item.

Since there is only one database, we knew that we could fix it with a carefully placed transaction and lock on the database. But we wanted to add a Cucumber feature so that we could be sure it was working, and to give us confidence that the bug would not come back again in the future.

  Scenario: Two users take next item simultaneously
    Given a user with login "ann"
    And a user with login "bob"
    And an available item called "Item 1"
    And an available item called "Item 2"
    When two users attempt to take the next item at the same time
    Then they should each have taken different items

Notice we can’t actually say who gets which item – it’s a race condition. We can only check that both of them have an item and that they are not the same item. We could alternatively check that both of the items have successfully been taken.

Testing this concurrency issue in Cucumber turned out to be somewhat tricky. We tried using simple Ruby threads in Cucumber, but it wasn’t properly simultaneously. I guess the single Cucumber environment still only does one thing at a time. So it was back to the Rake task.

When /^two users attempt to take the next item at the same time$/ do
  t1 = Thread.new { `RAILS_ENV=cucumber rake test:take_next_for['ann']` }
  t2 = Thread.new { `RAILS_ENV=cucumber rake test:take_next_for['bob']` }
  t1.join
  t2.join
end

We ‘join’ the two threads to make sure they’ve both finished before carrying on.

It’s slow because it loads up a whole new Rails environment for each of the Rake tasks, but that is exactly what we want to do, to mimic the concurrency of the production system.

The next problem we encountered was that Cucumber scenarios are run inside a transaction which means that a Rake task running outside of it cannot see the users and items we just created. So we had to tag the scenario as @no-txn so that they would be available externally and @clean-up-afterwards so that we could remove them from the database.

After "@clean-up-afterwards" do
  User.destroy_all
  Item.destroy_all
end

With this in place the Cucumber scenario failed as we hoped it would! Then it was simply a matter of creating a transaction from the moment we find the next item (with a database lock) until we have successfully assigned the item. This is a simplified version of what we ended up with:

class User < ActiveRecord::Base
  has_one :item
 
  def take_next_item
    transaction do
      item = Item.available.by_priority.find(:first, :lock => true)
      self.item = item
    end
  end
 
end

The Cucumber scenario passed and the problem was solved. In the live system, if two users now try to take an item at the same time, one of them has to wait a moment until the database has finished assigning to the first user so that it can assign a different item to the second user.

How would you have tested a concurrency issue like this? Are there better ways of imitating a multi-server production environment than the solution we came up with?

760th day at Eden

Friday, July 9th, 2010

We have a new intern at Eden. Tom Crayford studies Software Engineering at Sheffield University and is doing a 2½ month internship with us, with the possibility of becoming an apprentice at the end of it.

In the style of Tom’s two recent blog posts, First day at Eden and Second day at Eden i thought i might also write about my day, since it was a particularly satisfying one. It just so happens to be two years and a month (760 days) since i joined Eden!

Straight after this morning’s stand-up meeting, I had a quick debrief of a meeting we had with a potential new client yesterday evening. Then i helped Todd to write an email. We draft our emails on Google Wave these days, which is often fun. Four of us were editing the email at once, which means we quickly get to something we’re all happy with before sending it.

I went out for a walk with Frances to pay in some cheques and buy some Friday Treats for everyone!

At lunch time some of us had several rounds of TypeRacer in preparation for Learn To Type Correctly Week next week! I think it’s incredible how so many people have got enthusiastic about learning to type well after Corey Haines announced it. If you don’t believe me, check the twitter hashtag, #learn2typewk!

Something quite unusual happened after lunch. We had a message from Richard Knoll at Mercia Cycling Club in trouble and needing help because the site was not responding. Richard had found us on Google after searching for Ruby on Rails. I agreed to look at it with Tom for an hour and see if we could figure out what was wrong. We determined that rubygems and Radiant had been upgraded on the server and we needed to tweak a few configuration files. With help from Chris and Spencer, the site was back within the hour! Chris then helped me to raise an invoice for an hour’s work.

It’s interesting that we can do anything from a fast restore of an unresponsive website, to projects that take several months from start to finish, requiring two or three pairs of developers working at a time.

Tom and i continued to pair together for the rest of the afternoon. We were able to add value to a project to help a charity in Cambodia. I always learn something whenever i pair with someone. Tom is no exception and i very much enjoyed pairing together today. We all have things we can teach each other.

Tonight i think i might learn a bit from the Ruby Kōans, possibly study a bit of SICP, and definitely see who gets evicted from Big Brother!

Remote trio programming

Wednesday, January 6th, 2010

If pair programming is good, trio programming must be great, right?

Well, normally no, probably not, but today i had a trio programming experience that worked really well. Two of us were new to the codebase and together we learnt a lot from the person who knows the code well.

Of course, we all did not crowd around a single computer. That would not be comfortable at all. Due to the snowfall, most of the edenites were working from home today, so it gave us a great opportunity to find an effective way to pair remotely.

Initially we tried iChat screen sharing, but the screen updates are too slow to be satisfying. Steve had the idea of using GNU Screen so that we could all access the same terminal window via SSH.

Using a VPN to the office network, we were able to tunnel to Steve’s laptop and access the screen. In fact we found it useful to have two screens running: one for editing code in Vim and another screen for running Cucumber features. The exciting thing is, we don’t all have to look at the same screen at the same time: each person is free to switch screens on their own machine without affecting the others.

A Skype conference call completed the experience so that we could talk through our thought processes and learn the details of the codebase.

It was altogether a very profitable day. The snow, instead of being a hindrance today, helped us to find a very effective way of allowing three people to collaborate on a codebase.