pdx.rb codefest

Posted by John Labovitz Mon, 19 Sep 2005 15:27:00 GMT

Several members of pdx.rb got together on Saturday, 17 September 2005, for an all-day codefest/hackfest. The purpose was to implement some groovy and needed features for our website. Although we’re not yet finished, feel free to play with the development version.

The original ideas had been hashed out in several heated email discussions on the pdxruby mailing list, a face-to-face brainstorming meeting (digitized notes here), and some follow-up at the last monthly meeting. We decided we needed:

  • A “cat-herder” application to try to organize the somewhat anarchic pdx.rb group, specifically in planning and finalizing meetings.
  • A membership roster where pdx.rb members could describe themselves and provide links to their homepage and/or blog RSS feed.
  • A homepage that pulled together summaries of the planner and roster information and presented it in a dynamic form.

Many pdx.rb members are interested in XP/Agile programming techniques, so it was only natural that we try out some of those methods. A few folks had done a codefest (aka sprint), and enjoyed the experience, hence the suggested form of development: a single day of designing and coding, hopefully ending up with a workable/usable application.

We’d heard about the seattle.rb’s experience where they designed ahead of time, and then found that by the day of coding, all the tasks had been completed! So we decided to only have a vague, high-level idea of what we wanted, and do the detailed planning during the codefest itself.

The folks who participated were:

Robby Russell and Ben Bleything did a lot of pre-codefest work to get the development environment useful and comfortable.

Infrastructure

We’d booked the Green Room of the Rose & Raindrop on Grand Ave. in SE Portland; we had the room from 11am to 7pm. John Reed of the R&R had kindly set up a couple of tables in a big ‘T’, and had water and menus handy. Food/drink service worked out pretty well overall—the R&R was attentive to us without bugging us. And the food & beer were good. The R&R allows smoking at the bar, but we were removed enough that it wasn’t overwhelming. However, the next codefest should probably be at a nonsmoking establishment so everyone’s as comfortable as possible.

I’d brought extension cords and power strips, everyone brought a laptop (Mac or Linux), and we immediately created a spaghetti of cabling—even though each of us used the Personal Telco wifi connection at the R&R.

It took us a couple of hours to set up. I had assumed we’d spend an hour, but some folks still needed to install tools like Subversion, Rails, and the right Postgres adaptor. So there was a flurry of downloading, installed, debugging, and installing again. We all learned a lot, so the extra time was worthwhile. And next time, given the same group, setup will be quick.

The wifi connection worked out great, minus the annoying habit of the access point timing everyone out after an hour, regardless of activity.

Robby had graciously contributed space to host the website on his Planet Argon host, as well as a Subversion repository and subdomains to access both the repository and the development version of the website. We also had a development mailing list (open to anyone) and an IRC bot that watched for Subversion commits and summarized them to the #pdx.rb IRC channel.

Everyone who showed up got commit access to the Subversion repository. There were surprisingly few problems using Subversion, even for folks who had very little or no experience.

Probably the biggest stumbling block was setting up the databases. I’d assumed that each of us would have local databases to test & develop against; that’s the way I’ve done most of my Rails development. However, there was enough trouble getting local databases installed that we decided to use a central database.

Since we didn’t have a server per se at the codefest, I hosted the DB on my Powerbook (with configuration help from Lennon), and everyone set up their own config/database.yml just using the root postgres user. (A future codefest would do well to get this running ahead of time, and properly secured.)

It turned out that having the central database was nice because the development data - which was added incrementally, not through fixtures or undumped SQL - could be shared.

Given the setup delay, the test I should have recommended to do before the day of the codefest would have been:

$ svn co http://svn.pdxruby.org/repos/www
$ cd www
(edit config/database.yml)
(create databases & tables, if necessary)
$ rake

If all that worked, each of us would have been good to go, needing only commit permissions and perhaps a quick change to config/database.yml.

Design

Once we were all ready to code, we sat down with a big pad of paper and did some brainstorming. I scrawled while everyone threw in ideas of what made up the project. These were raw “mind-map” diagrams, not process-oriented flowcharts. [I should probably put up a link to an image here…]

We tried to keep the brainstorms flowing, not getting bogged down into implementation details. To keep the project simple, we dropped less-important features pretty quickly. We also dropped things if we couldn’t figure out exactly how they worked, or if they couldn’t be easily explained.

From the brainstorming diagrams, we came up with a set of behaviors, each of which we wrote on a separate index card. (This “behavior-driven testing” is an idea I got from listening to a podcast by Dave Astels.) For example:

  • “Owner can give event to another participant.”
  • “Participant can change their RSVP and comment.”
  • “Anyone can view the members list.”

That was really it for each behavior—there was no detailed task list, or estimate of complexity or time. We ended up with about 30 behaviors, I believe.

Only after we did the cards did we realize that we’d pretty much dropped the feed-aggregator—at least we didn’t have any behavior for it! Everyone was okay with that; we knew we had plenty to work on with just the planner and member roster.

Then, going through both the behaviors and the brainstorming diagrams, we came up with a schema from which we could make models. Caleb, who knows SQL and Postgres well but was a beginner at Rails, created an SQL file as we talked.

(It should be mentioned that only a couple of folks had much Rails experience; most had done a few toy/demo/starter applications, and a few had only looked into Rails, but never tried it.)

Finally, we shuffled the cards and divided them into piles and passed them around.

Jason pointed out that something we missed in the design phase was the classic “user stories.” I think we actually did implicitly include them, since the coders would be the final users for this particular project. But it might have been good to be more explicit about them to prove our assumptions of what behaviors were needed.

Code

We quickly realized that the behaviors fell into two sets: behaviors of the planner, and behaviors of the membership roster. We agreed that anyone could trade a card if it was something that they couldn’t do yet, or was better done by someone else who was working on that part.

Perhaps because of the two sets of behaviors, or perhaps because there were Rails novices, we organically divided into three groups. This was great for discussing the details of the behaviors, and it also brought us quite naturally into a form of pair programming. (I’d brought a larger display, so there was actually trio programming.)

On the downside, we weren’t set up the best for pair programming. Laptop screens are small and often don’t have a wide viewing angle, and although I had a large screen, I had an ergonomic keyboard that was virtually impossible for other folks to type on. However, just having another pair of eyes on the code as one types is extremely helpful, and also gets you out of ruts, pre-mature optimization and refactoring, and makes you new friends. ;)

Laying our cards out in front of us made it pretty easy to find the first task. There were lots of behaviors that couldn’t be implemented until other behaviors existed, so we tried to find the most fundamental behavior to implement. For example, the first behavior our group implemented was “Anyone can register to become a member.”

I’d been using test-driven development in my personal Rails projects, and was looking forward to trying it in a group. However, our group quickly found it to be cumbersome and confusing. I don’t think it was the testing itself, but rather that the testing framework assumes a certain knowledge of Rails, and there was a wide variation in that knowledge in the group. So we plowed ahead and just coded instead.

There were definitely some fits & starts. Some of it was the platform: not being Rails wizards, we over-implemented, then threw away code when we realized there was a far easier way (a common situation in Rails). We also had to really think through the meaning of some behavior—what does registration really do? How do people login? Where is that login information kept?

I found that absolutely the most productive moments were those times we looked away from the screen and asked ourselves “How should this really work?” The answer wasn’t in the code, nor on the cards: we had to think through the situation and consider various options—and there was always the right option, which we then coded up.

Interface

Perhaps because of the nature of the project, there wasn’t a lot of overlap between the planner and membership tasks. Where there was, it was really excellent to just have someone pipe up and say, “Hey, do you have a logout method I can call?” and hear either “yes” or “we’re working on it.”

What we didn’t do, but probably should have, was to take breaks periodically and review what has been happening. (In the XP world, I think these are stand-up meetings.) Although we accomplished significant progress in our project, one group often didn’t know what was happening in the other group until there was a problem, or until the end of the day. Probably the easiest way to solve this would be to set a timer to go off every hour or so.

Another thing we didn’t do was to switch off between tasks. So at the end of the day, about half of us knew a great deal about how the membership system worked, but very little about the planner system—and vice versa. It would be nice to play musical chairs among coders and systems.

Release

We did pretty well on releasing our efforts throughout the day. Folks checked their code into the repository promptly, and because of the Subversion post-commit hooks, those commits got published to IRC and the development mailing list for anyone else to pick up.

But because of our lack of status/stand-up reviews, we didn’t really integrate often. For such a small project, it probably wouldn’t have made a difference, but I could see how a larger or more inter-twingled project could get caught up and lose track of where other groups are.

We also didn’t continuously integrate on the dev.pdxruby.org development server. This would have been nice, since it would have been a single place to go and see the progress of the whole system, whether from the codefest participants or observers outside the codefest. What I should have done, but didn’t, was to set up an automatic update on the development server whenever a commit happened (This is not trivial, however, if the schema changes; it also might be good to set up something like CIA (see HowTo) and only update the development server if all tests pass.)

At the end of the day, I finally did attempt to get the development server updated, but ran into a problem with the Postgres adaptor on the server. We eventually fixed the problem and updated the server, but it didn’t feel very “agile” by then.

Follow-up

Not surprisingly, we ran out of time to finish all the behavior cards on the day of the codefest. I’ve checked the cards’ text into the repository, so anyone can work on them.

We ended up with a partially working system, which is great—my fear was that we’d end up with a broken system, and lose momentum to fix it. Since Saturday, we’ve already had a few commits to portions that were rough or mildly busted, and hope there will be more.

Lessons

  • Make it fun!
  • Create a reliable infrastructure well ahead of time. Come up with a checklist, but also have a definite way to test that checklist.
  • Plan, but plan quickly. Don’t hold on to complicated ideas.
  • Split into functional groups, but make sure there’s enough communication to know who is doing what.
  • If possible, do pair programming. Trade partners, so everyone learns the whole system.
  • Release early, release often. Extend this to a development site that is automatically updated for each commit.
  • Have a definite follow-up plan, whether finishing or maintaining a project.

And finally…

It was a great experience doing the codefest. Although it took more organization than I had thought, the time spent was well worth it. I got to know some of my fellow pdx.rb’ers a lot better, and learned quite a bit, both about Rails and cooperative coding.

I’m looking forward to the next codefest, whatever it may be!

Tags , ,  | no comments | no trackbacks

Comments

Trackbacks

Use the following link to trackback from your own site:
/articles/trackback/3

Comments are disabled