Sunday, April 26, 2009

How to run a Developer Book Study

Have you seen "Everything I Know" from Buckminster Fuller? He recorded 42 hours of lectures detailing his entire life's work. I tried to read the transcript but it was unbearable. More limited in scope is my "Everything I Know about Developer Book Studies". It may not be better than Bucky's, but it's certainly easier to get through. So here are my experiences from doing a few book clubs a year over the last 3 years.

Picking a Book
This is way harder than you'd think. Creating a web survey for your team or devising elaborate instant run off voting schemes aren't worth the effort. Better to gather several ideas and then let one person decide... naturally that person is the one organizing the book study in first place.

But picking a good book is still hard. Don't trust Amazon ratings. Many of the ratings are given by people compensated to give a review. There's a lot of publishers handing out free books in exchange for public reviews, so 4 stars doesn't mean a whole lot. Jolt Awards on the other hand have proven to be a very reliable source of good books. Even then, it can be a crap shoot. "The Pragmatic Programmer", for instance, is a great book but we had a terrible time finding meaningful conversation around it. Perhaps some books are just meant to be read alone.

Finally, don't pick anything too long. A lot of people (me included) have a hard time not reading every page of a book. In a larger group you'll surely have a few. Dragging a book club out over several months saps your energy. Low 300 pages is my limit. The bigger font the more better, too!

Creating an Invite List
Do you invite everyone on the team? Everyone in the company? The remote office? Contractors? It depends on what you're trying to accomplish with the book study. A team only book club is good if you're reading a book that specifically applies to your project, while an entire company book club is good to promote practices across teams. Want to jumpstart agile adoption with a book study? Invite the team only so you can discuss specific practices to start using that make sense for you. Want to upgrade your standard coding practices by reading Clean Code or Effective Java? Invite the entire company, because quality discussions don't depend on a specific team context.

Remote employees are hard. Conference call etiquette always seems to break down. It's most painful for the remote person, so he or she needs to be especially motivated to benefit.

Having several people remote can work. We did a Design Patterns study and included a team from a different company. We agreed not to discuss work specifics and it turned out pretty well. We read Head First Design Patterns and GoF at the same time, and one person from each site presented on the same pattern from the different texts. The room with more people did dominate the conversation though.

As for contractors, I like to invite them and explain the time is non billable. Few accept but I feel it's a nice gesture. Does that sound condescending? It's not meant to be.

Choosing a Format
The format is one of the most important decisions, and different books require different formats. Soft skill books, especially agile, don't need much structure. Everyone has an opinion and everyone can generally contribute to the discussion (not always a good thing). Technical books need more structure. We did Java Concurrency in Practice and settled on a format where each person is assigned a week, and that person presents back to the group as if they hadn't read the chapter (which they had in fact read). No one was an expert on concurrency, so without the format we had nothing to say. With the format, even people who hadn't had the time to read that week benefited.

Try to have a format that produces decisions. "We will start test driven development" or "We will document monitoring concerns in designs". Without action after the book study you're just sitting around talking. Try to use what you learn at work with specific actions and decisions. Writing all your decisions and recommendations down can help you plan your course of action after the study is over. Don't bother taking minutes though; it's unlikely that anybody wants to read them.

Also, it's nice to give everyone something to take away. If it's your turn to lead then have a 2 page handout ready with your material or your code samples. Handouts are much better than slides because they can eventually be transformed into blog posts or internal trainings.

A final bit of logistics: schedule the meeting for 1 hour, the room for 1.5 hours, and try to finish in 45 minutes. If no one has anything to say then cut losses and run. If the discussion is productive then stay a little late.

Reading the Book Correctly
I like to set an aggressive schedule to keep the study under a two month span. Any more and you get burned out and bored. Once a week for two months is a lot. Our Release It! study did four every-other-week meetings and worked great. Keep it short.

Read with a highlighter. Highlighting text forces you to read the important passages twice, making them more memorable. You'll remember a book better if you've highlighted it, it's easier to come back and find passages later if they are marked, and it's easier to gather up your notes if the book is marked up. And bringing a written set of notes to a free-form session is very helpful, it helps keep the conversation on the most important topics.

As for the pace, I have two bits of advice:
1. Don't read ahead; you'll forget the material by the time the sessions come around.
2. Read the entire book ahead of time; you'll have better discussions because you understand the book's entire context and the pressure will be off to complete some sort of weekly reading schedule.
"Do I contradict myself? Very well, then I contradict myself, I am large, I contain multitudes." -Walt Whitman. See? My copy of Song of Myself was highlighted, so I could easily find that passage! (OK, I admit I googled it).

Promoting the Event
Showing the value of the book club to the other developers and managers can build interest and get more participants in the next club. Let others know what they missed by posting your notes on your blog or wiki, or holda training session on the book content at the end of the study.

I like to let managers know who is and isn't participating. If some teams aren't present in the studies then the managers can apply pressure to get more people involved. Being known as the guy who organized the book club doesn't hurt your reputation either.

Lastly, ask to be reimbursed for the books. It can't hurt. My employers have always been happy to buy books, I'm surprised when people are afraid to ask.

Take a break
So your bookclub was awesome... now don't do it again! Give yourself some time to recharge your batteries and implement all the great ideas. It'll also give you time to email me with your lessons learned. I'd love to hear them.

Sunday, April 19, 2009

Release It! Review in "Quotes"

On Stability...

"Every integration point will eventually fail in some way" - Michael T. Nygard
They sure do... and the book contains patterns to follow, like the Circuit Breaker, to ensure your system stays alive when the other system dies.

"Generating a slow response is worse than refusing a connection or returning an error" - Michael T. Nygard
The book explains how slow responses tend to propagate upward from layer to layer in a pattern he calls "cascading failure". There are several patterns to address this issue, especially Timeouts.

"Hope is not a design method." - Michael T. Nygard
Quotable nuggets like this make the book an entertaining read from start to finish.

"Ohnosecond: that very short moment in time during which you realize that you have pressed the wrong key and brought down a server, deleted vital data, or otherwise damaged the peace and harmony of stable operations." - Michael T. Nygard
It'd be alright with me if I never had credentials to log onto another production server in my life.

"Data purging always gets the short end of the stick. It certainly doesn't demo as well as... well, anything else in the world demos better than data purging." - Michael T. Nygard
There's not a lot to say about purging except, "Why aren't you doing it?" Still, the book contains a good call-to-arms about the topic.

On Capacity...

"Nothing is as permanent as a temporary fix" - Michael T. Nygard
The last chapter contains a wonderful description of Enterprise Architecture in which a crystal palace has been built and calcified, and now developers tiptoe through the code speaking in hushed tones, trying not to touch anything. Reading this passage was worth the cost of the book alone.

"Storage is a service, not a device" - Michael T. Nygard
The real cost of hardware is thoroughly explained, and Michael shows how the real cost of ownership on local storage is sometimes seven times higher than the actual hardware cost. As for processing power, he introduces the concept of a "Forklift Upgrade"... adding CPUs to a box is pretty cheap, unless it requires a new box and your box weighs two tons. Makes you think differently.

"Some technologies just beg to be misused. Take bottle rockets. No matter how many warning labels manufacturers put on bottle rockets it's still a firecracker with a handle." - Michael T. Nygard
Or the combination of StringBuffer, SQL, and a JDBC connection. Oh God, please don't build up a SQL command by combining all these. The book's coverage of this one is a little more nuanced than mine.

"Nobody deliberately selects a design with the purpose of harming the system's capacity; instead, they select a functional design without regard to its effect on capacity." - Michael T. Nygard
Design for Capacity... can you honestly claim this as one of your design principles? This is different than designing so you don't ruin your capacity. Mr. Nygard explains how this isn't premature optimization and provides concrete patterns to follow to get capacity.

"Factor the cost of generating content out of individual requests and into the deployment process" - Michael T. Nygard
If web content is static between releases, then precompute that content as part of the build. This is a good example of how the book contains specific, concrete advice, and isn't just a collection of high-level maxims.

On Availability...

"The proper way to frame the availability decision is in straightforward financial terms: actual cost vs. avoided losses." - Michael T. Nygard
Service Level Agreements (SLAs) are given a fair and developer focused treatment, complete with some light math. See his blog posts on Reliability Math Getting Real About Reliability for a flavor of how some math can actually help explain some of these concepts (although those posts get into a lot more math than the book did).

"Most of the time, the real culprit [for deployment and production defects] is a mismatch in topology between QA and production" - Michael T. Nygard
I spend a staggering amount of time trying to replicate defects in development. Part of this are the hidden dependencies that come with housing several components on the same machine in QA but not production or differing network configurations like having firewalls set up between servers in production but nowhere else.

"A running application can be interrogated for its internal state, but a halted one cannot." - Michael T. Nygard
For me, this was non obvious. This quote comes in the context of building a clean start-up sequence for all of your system components, and not accepting work until the entire system is running successfully. Compare this to a system that aborts and exits if something fails during start-up. Which system would you rather troubleshooot? Which system has a better chance of being able to tell you what is wrong with it?

"Java GUIs make terrible administrative interfaces for long-term production operation." - Michael T. Nygard
GUIs make terrible administrative interfaces, whether they be desktop or web. Scriptability is advocated here, and exposing your application as JMX MBeans is held up as an excellent example of how to do it right without much effort.

On Transparency...

"Without transparency, the system will drift into decay, functioning a bit worse with each release." - Michael T. Nygard
Many of the book's concepts are explained with analogies from outside computer science. For instance, eutrophication from Biology, bulkheads from the shipbuilding craft, and circuit breakers from electronics are all used to explain some of the patterns and anti-patterns laid out. Part of the joy of reading this book is finding those quotes and concepts from other scientific fields that somehow apply to our craft. The writing goes beyond the obvious tie-ins to entropy and constraint systems. Readers love a diverse bibliography.

"Can we make it through the holiday season? (Notice that this requires a projection about a projection, which doesn't just double the possibility of error but squares it.)" - Michael T. Nygard
It's OK to think in mathematical terms. Really, it is. This book makes you think differently about capacity, availability, and reliability by bringing it back to some simple numbers.

"A startling number of business-level issues can be traced back to batch jobs failing invisibly for 33 days straight." - Michael T. Nygard
With better monitoring you'd have had 32 days to fix the issue. Now it's the 33rd and you're working the weekend. Enjoy it. By the way, this is a design issue, not a reporting issue.

"Logging should be aimed at production operations rather than development or testing. One consequence is that anything logged at level "ERROR" or "SEVERE" should be something that requires action on the part of operations." - Michael T. Nygard
You can show up at work Monday and start applying this advice in your code, and you can show up and start applying the principles in your designs. That's a unique combination for a book. Release It! blends enjoyable writing, high level conceptual thinking, and lower level implementation steps. My work did a book club on Release It! and within a few weeks it has changed the flavor of our design sessions. I really enjoyed this book and highly recommend it to others.

Saturday, April 18, 2009

Testing Groovy AST Transformations

There's been a lot of work recently on Groovy AST Transformations, both in the language and on this blog. This post describes two tips for testing your transforms: use the AST Viewer in the GroovyConsole 1.7 snapshot and use a simple test harness with your IDE's debugger.

The AST Viewer in the 1.7 version of GroovyConsole shows you the AST generated from your script. It is an easy way to explore the AST generated by the language and your transformation. Just write your script as normal, and open the viewer with the Inspect AST option under the Script menu. You don't need to run the script even. Here is a sample script:

And here is the AST viewer:
The instance field synthesized by the @Singleton annotation is highlighted in the grid. The tree view shows all the ClassNode and ScriptNodes that were generated and you can expand the tree to see all the descendents.

As you can see, you can select the CompilePhase you compile to, and since the window is non modal you can make script edits and click the Refresh button to redisplay the results. As you click nodes in the AST viewer, the code that generated that node is highlighted back in the main console window. It's literally minutes of entertainment to write a script and click the nodes, watching how the source code contributes to the result. Fun stuff!

This feature is in 1.7 which right now is still in beta. That's OK, it's easy to get 1.7 Just go to the continuous integration website: http://build.canoo.com/groovy/. Just click "Build Artifacts" then "Deliverables". You'll want to download the groovy-all jar file.

My other tip is to use a small test harness to debug your transformation within the IDE. The following code gives you a small function to compile code in process, so any breakpoints in your transformation will be triggered. Just pass the function a File object of your sample script and the CompilePhase you're targeting. Any dependencies in your target script will still be valid during this test execution.

import org.codehaus.groovy.control.CompilationUnit
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.CompilerConfiguration

private void compile(String script, CompilePhase compilePhase) {
def scriptName = "script" + System.currentTimeMillis() + ".groovy"
GroovyClassLoader classLoader = new GroovyClassLoader()
GroovyCodeSource codeSource = new GroovyCodeSource(script, scriptName, "/groovy/script")
CompilationUnit cu = new CompilationUnit(CompilerConfiguration.DEFAULT, codeSource.codeSource, classLoader)
cu.addSource(codeSource.getName(), codeSource.getInputStream());
cu.compile(compilePhase.getPhaseNumber())
}

def file = new File("/path/to/Tester.groovy")
compile(file.text, CompilePhase.SEMANTIC_ANALYSIS)
There are definitely more tools coming, like the AstBuilder objects designed for 1.7. The builders are still in development and I'd love to hear your feedback on the GEP. Email me or the dev list with feedback.

Also, I'll be presenting on "Groovy Compile Time Metaprogramming" at the June CapJUG group in Madison, Wisconsin. It'd be great to see you!