Thursday, April 8, 2010

Philly ETE: Session 1

Creating Multithreaded Code Using TDD
-- Venkat Subramaniam

I've chosen this session over the others, mainly because I think Venkat is a seriously smart programmer with a great deal of interesting knowledge to share. I'm curious to see how TDDing multithreaded code diverges from typical TDD practices.

Other questions I have before we start --
If I program in Ruby, should I ever do this, even if the TDD practices are awesome?
Will we get some TDD examples in an FP language like, for example, Clojure? That would be awesome. But I think I have a good enough grasp of Scala to follow along there too.

Interestingly enough, Venkat started out trying to disprove the validity of TDD in multithreaded programming. But in his attempt, he found that he actually WAS able to. Not only that, but the TDD methods he employed saved hours of debugging multithreaded code to find a couple of bugs.

Lots of talk about the importance of TDD. Probably a nice talk for inexperienced TDDers, but for me and the two Cyrus developers to my left, Venkat is preaching to the choir.

There won't be any slides during this talk. I have the highest respect for speakers who run their talks this way. It's risky and sometimes ugly, but it's the closest thing to real-world programming that we can get at a conference. And application to the real-world is what we're all trying to get out of these two days. But I digress.

We're up to the "Let's give it a shot" section. I'm excited. Running this example using Java on IntelliJ IDEA.

First we start with a "canary" test. It is a stupid test that does something like "assertTrure(true); I do something similar with my new Ruby test files, but I don't keep them. There might be a reason to keep them around, particularly when the application is multithreaded. We're starting our example with a couple of classes, MultiValueMap and MultiValueMapTest.

I'm doing my best to keep up with the code. However, I'm using vi (don't have IDEA installed here) so it's going to be rough around the edges. I might post what I have at some later point after I clean it up. No promises though.

Best argument for TDD "it prevents Whack-a-Mole software development."

Now to the multithreaded stuff. If we make a threading testcase, and to make the test pass we make our public void class a public synchronized void class, we run into a wall. We can't test this easily. We need to avoid sticking 'synchronized' in this case.

The next tool to reach for is mocking. But Venkat suggests a more stripped down version of mocking. The result: MyLockMock which extends, not a mocking library, but ReentrantLock.

After we get some threading tests passing, we look into exception handling. He forgoes putting 'try' and 'catch' statements until he can write a properly failing test. I lost the ability to keep up coding along with Venkat at this time, but I got to witness some interesting incremental TDD.

The message is repeated in a number of ways: make it as simple is possible, move slowly, test one discreet piece of functionality at a time. Simple advice that is much better given through coding that through a bunch of slides or beating us over the heads with it.

Venkat never created a single thread to test his multithreaded design. This was the 'revelation' that led him to believe that TDD was possible, even simple, with multithreaded code.

For C#, Venkat recommends anonymous delegates. Good to know in some of my own toy projects.

A personal aside:
Venkat is awesome! He's funny, engaging, takes the right amount of questions, rolls with the changes and questions of the audience and reflects it in his live coding. What an accomplished speaker. I'd watch this guy give a talk on milk pasteurization (or something else I care equally little about).

No comments:

Post a Comment