It happened on a project I was working on that we had to implement a divide & conquer algorithm using our background jobs processor, in this case we were using sidekiq. Implementing this using sidekiq can be quite challenging since all the workers are independent and they do not trigger any callback once they’re done.
Last year before I joined Pivotal Labs me and my friend Raphael Costa participated in a brazilian Rumble, inspired by Rails Rumble ran by the folks from Startup DEV. It was a very interesting experience and I learned a lot from it. We won first prize, and I want to tell how we did that, and why I would change some things if it was a real project supposed to live more than 48 hours.
First, if you don’t know what a rumble is, a rumble is a developer’s competition where you have a very limited time to develop an app, your result is evaluated by some folks and the best app (according to their criteria) wins. In the case of Rails Rumble or Startup DEV rumble we had 48 hours over a weekend.
The plan can and should be draw before you start the rumble. When the clock starts ticking you have to laser focus in implementing everything you can.
First thing you need is an idea, it doesn’t need to be revolutionary it just needs to be implementable and easy. If it’s revolutionary, bonus points for you. Once you have an idea you have to describe in detail what is the featureset you are looking for.
When you have you featureset, you have to remove everything, EVERYTHING that is not absolutely required for your MVP, sort the features you removed in nice-to-have order in case you have spare time at the end.
Draw your mockups on paper and have them ready and attached to each story you selected as part of your MVP, if you have a designer, great, make him draw more detailed wireframes, if you don’t then you’ll have to use the tools the world provide you, such as bootstrap or foundation or whatever you prefer, do not waste time in things you are not expert in.
Split tasks based on capacity, in our team we were two developers, I had more experience with dev-ops (and we had to deploy our app to a VPS that was provided by the organization) he had more experience with UI/UX design, so I barely thought about how the app should look, and he barely used ssh.
Applying the plan
The basic procedure is: pick a story, assign it to you, implement it as quick and simple as you can, deliver it asap, move on.
Stay in sync, you have to know what’s happening with the other folks in your team, if your team is larger than 2, it gets more and more dangerous. You do not want to spend time resolving complicated merge conflicts so make sure the tasks are well parallelizable and that no one is stepping in no one’s toes. We had quick check-in (2 minutes, standup style) every 2 hours.
We knew what we were capable of, so we didn’t try to do anything other than that. If you never implemented a payment gateway, don’t try to do so in a 48 hour project, you will waste time and you won’t be able to finish. We knew how to TDD and we had paired before, but these were things that we were not used to do, processes not clear in our minds, we would have to learn it on the go and we would fail if we tried. When you try something new you will certainly spend time figuring things out. So because of that we didn’t even try, we did not test, we did not pair.
Commit often, commit every time, on every change. This avoids complicated merge conflicts and saves you a lot of times. Write decent SHORT commit messages so you team can understand what is that that you did just by parsing the message quickly. Pull often, see the log,
git log --graph --oneline was the command we used to quickly parse messages, alias it to something simple, like gl, for example. Once you finish a feature, deploy it. Make sure everything works properly in your deployed environment.
We finished everything and more with about 2 hours to spare, in this 2 hours we looked for bugs, found some and fixed them. This spare time is essential specially if you are not TDDing, you will find problems.
What would I do differently
First of all, if you want your app to continue after the 48 hours you have to TDD, on the next day after the competition we looked at the code and it was only OK, it wasn’t bad or anything, but it was very hard to trust it and make changes because without any tests you have no confidence on doing it. The solution for us would be rewrite the app TDDing or backfill, and backfilling is very painful.
Skiping the tests is very risky, you may break everything without knowing, and that would make you fail, we took that risk and it worked for us. I wouldn’t do that again, I would TDD next time even if that means reducing the scope even more, it’s too hard to develop a real app without it.
Pair programming and TDD are things that make you very productive on the longer run, on a 48 hour crazy competition it might not be the best thing to do if you’re there to win and your team is only composed of two people. If you have a really small and simple featureset and your team has experience you can get away without it and it would be faster on this 48 hour streak. It is very likely that you will have to rewrite your app after tho.
I would pair if I had a team of 4, a single pair may not be the best for a 48 hour thing, you kinda need the parallelism on this short project. The ideal setup would be two pairs tho. More than 2 parallel developer stations would probably be a bad thing.
Participating is fun, we had a lot of fun, there were several good projects on the competition and it was awesome. If you ever have the opportunity to participate in one of these you should, it’s very tiring but it is worth it at least once. If you’re interested our project is still online at agrupe.se (it’s in portuguese, sorry, google translate).
When I’m doing outside-in TDD (and that is basically whenever I’m coding) I often process things as a stack. I write an acceptance level test, run it. It fails (hopefully), so I write a lower level test, let’s say, a controller test. It fails. I might need go further and write a model unit test.
When I finish the inner TDD loop (say, unit on a model) I want to “pop the stack” and run the controller one, having that done, I want to run the acceptance test again. Often times the inner part of the loop takes long enough that you might forget what exactly what you were doing before, lose track of the files you had and ask your pair “what was the feature again?”.
This is a general problem and I think every editor can have a tool to solve this. I couldn’t find it for the editors I use on a daily basis (Vim, Sublime Text or RubyMine, depending on who I’m pairing with). So I got something that we use here at Pivotal and implemented my solution on top of it for Vim.
The solution we have here was created to solve yet another problem, how to run tests from Vim asynchronously, that means, without blocking your editor. Most development environments have this functionality and I think it’s quite useful specially when pairing.
There are several ways to accomplish it in Vim, and we have been doing this using a unix pipe thanks to my coworker and good friend, Andrew Bruce.
The reason why I like this setup very much for pairing is because it raises the visibility of the test results, I like them always on screen so both can see it all the time regardless of how fast you can visually parse it, it looks somewhat like this:
So you have you code in a window and your test results always visible. As a bonus, if you are on OS X and using iTerm2 you can
⌘ + Click a filename:line number to open the file in MacVim (Preferences -> Profiles -> Advanced, Open With Editor…, MacVim).
This is all very good and helps a lot. But I wanted a bit more, the first thing I noticed is that I kept wanting to run arbitrary commands that our “test_server” don’t support.
My fork of Andrew’s idea, vipe, is a more generic command pipe, that runs anything. With that I am able to send commands to the terminal and maybe map a key to it. For example
:nmap ,t :Vipe ruby <c-r>%<cr> for simply running a ruby script with
,t. To do that I removed all the ruby/rspec/rails specific functionality from the original version and moved that into my personal vim config.
And then I implemented my most wanted stack of commands in Vipe. Running a command will automatically push it into the stack, you can simply run
:VipePop and it will run the previous command, as simple as that. Similarly
:VipeRerun reruns the last command.
And that’s about it, Vipe is a command runner for vim that has a command stack and allow you to run any arbitrary command you want, I haven’t spend so much time perfecting and I think there is space for improvement. I hope you find it useful.
Pairing is an amazing activity if you and your pair can do it right, it is one of the things we value most here at Pivotal Labs. It is also one of my favorite aspects of extreme programming since it’s the thing that makes me learn, teach and grow everyday as an engineer.
Being good at it helps you and your pair enjoy the workday, keep motivated and therefore, productive.
During the last months I have learned a lot about pair programming and I am trying to perfect this everyday. I have noticed a couple things that I think can help a person be a better pair.