<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Magpiebrain &#187; Development</title>
	<atom:link href="http://www.magpiebrain.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.magpiebrain.com</link>
	<description>The blog of Sam Newman</description>
	<lastBuildDate>Wed, 28 Jul 2010 21:02:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Executing A Command Line Program With Clojure</title>
		<link>http://www.magpiebrain.com/2010/06/20/executing-a-command-line-program-with-clojure/</link>
		<comments>http://www.magpiebrain.com/2010/06/20/executing-a-command-line-program-with-clojure/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 11:34:01 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[clojure]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=848</guid>
		<description><![CDATA[Updated to reflect some feedback and one example of using commons-exec as an alternative to the plain old Runtime.exec Second Update to reflect use of shell-out &#8211; thanks Scott! Basic Making use of clojure.contrib.duck-streams: (ns utils (:use clojure.contrib.duck-streams)) (defn execute [command] (let [process (.exec (Runtime/getRuntime) command)] (if (= 0 (.waitFor process)) (read-lines (.getInputStream process)) (read-lines [...]]]></description>
			<content:encoded><![CDATA[<p><em>Updated to reflect some feedback and one example of using commons-exec as an alternative to the plain old <code>Runtime.exec</code></em></p>
<p><em>Second Update to reflect use of <code>shell-out</code> &#8211; thanks Scott!</em></p>
<h3>Basic</h3>
<p>Making use of <code>clojure.contrib.duck-streams</code>:</p>
<pre class="brush: clojure;">
(ns utils
 (:use clojure.contrib.duck-streams))

(defn execute [command]
  (let [process (.exec (Runtime/getRuntime) command)]
    (if (= 0 (.waitFor  process))
        (read-lines (.getInputStream process))
        (read-lines (.getErrorStream process)))))

...
user=> (execute "ls")
("MyProject.iml" "lib" "out" "src" "test")
</pre>
<p>It could be improved obviously &#8211; for example catching some of the potential <code>IOExceptions</code> that can result to rethrow additional information, such as the command being executed, or the ability to take a <code>seq</code> of program arguments.</p>
<h3>Error &#038; Argument Handling</h3>
<p>This version adds some basic (and ugly) exception handling, and also handles spacing out arguments passed in (so passing <code>"ls" "-la"</code> gets processed into <code>"ls -la"</code>):</p>
<pre class="brush: clojure;">
(defn execute
  "Executes a command-line program, returning stdout if a zero return code, else the
  error out. Takes a list of strings which represent the command &#038; arguments"
  [&#038; args]
  (try
    (let [process (.exec (Runtime/getRuntime) (reduce str (interleave args (iterate str " "))))]
      (if (= 0 (.waitFor  process))
          (read-lines (.getInputStream process))
          (read-lines (.getErrorStream process))))
    (catch IOException ioe
      (throw (new RuntimeException (str "Cannot run" args) ioe)))))
</pre>
<h3>Using <code>commons-exec</code></h3>
<p>I had some problems with hanging processes, so knocked up a version using <a href="http://commons.apache.org/exec/">Apache&#8217;s <code>commons-exec</code></a>. This version has the added advantage of killing long-running processes, and I folded in Steve&#8217;s suggestion for a better way of splicing in the spaces in the command line args (see <a href="http://www.magpiebrain.com/2010/06/20/executing-a-command-line-program-with-clojure/#comment-21468">his comment</a>). <code>commons-exec</code> is part of the special sauce inside Ant, so is a rock solid way of launching command-line processes (well, as rock solid as Java gets). </p>
<p>The use of the <code>ByteArrayOutputStream</code> is probably inefficient, and again, decent error handling is left as an exercise to the reader. </p>
<pre class="brush: clojure;">
(defn alternative-execute
  "Executes a command-line program, returning stdout if a zero return code, else the
  error out. Takes a list of strings which represent the command &#038; arguments"
  [&#038; args]
  (let [output-stream (new ByteArrayOutputStream)
        error-stream (new ByteArrayOutputStream)
        stream-handler (new PumpStreamHandler output-stream error-stream)
        executor (doto
                  (new DefaultExecutor)
                  (.setExitValue 0)
                  (.setStreamHandler stream-handler)
                  (.setWatchdog (new ExecuteWatchdog 20000)))]
     (if (= 0 (.execute executor (CommandLine/parse (apply str (interpose " " args)))))
       (.toString output-stream)
       (.toString error-stream))))
</pre>
<h3>Using <code>clojure.contrib.shell-out</code></h3>
<p>Many thanks to <a href="http://www.magpiebrain.com/2010/06/20/executing-a-command-line-program-with-clojure/#comment-21520">Scott</a> for this.  <code>clojure.contrib</code> supplies the very neat <code>shell-out</code>:</p>
<pre class="brush: clojure;">
user=> (use 'clojure.contrib.shell-out)
nil
user=> (sh "ls" "-la")
</pre>
<p>I haven&#8217;t probed further to see if this deals with my hanging process problem, but it certainly doesn&#8217;t seem to have any support for killing timeout processes. If you&#8217;re worried about runaway tasks, the <code>commons-exec</code> version above might be the right choice for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/06/20/executing-a-command-line-program-with-clojure/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Clojure, Partially Applied Functions And Java Interop</title>
		<link>http://www.magpiebrain.com/2010/06/19/clojure-partially-applied-functions-and-java-interop/</link>
		<comments>http://www.magpiebrain.com/2010/06/19/clojure-partially-applied-functions-and-java-interop/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 19:00:11 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[clojure]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=841</guid>
		<description><![CDATA[I&#8217;ve been playing around with partially applied functions in Clojure, and have hit an interesting snag when dealing with Java interop. First, lets examine what partial does in Clojure, by cribbing off an example from Stuart Halloway&#8217;s Programming Clojure: user=> (defn add [one two] (+ one two)) #'user/add user=> (add 1 2) 3 user=> (def [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with partially applied functions in Clojure, and have hit an interesting snag when dealing with Java interop. First, lets examine what <code>partial</code> does in Clojure, by cribbing off an example from Stuart Halloway&#8217;s Programming Clojure:</p>
<pre class="brush: clojure;">
user=> (defn add [one two] (+ one two))
#'user/add
user=> (add 1 2)
3
user=> (def increment-by-two (partial add 2))
#'user/increment-by-two
user=> (increment-by-two 5)
7
</pre>
<p>What <code>partial</code> is doing is partially applying the function &#8211; in our case we have applied one of the two arguments our <code>add</code> implementation requires, and got back another function we can call later to pass in the second argument. This example is obviously rather trivial, but partially applied functions can be very handy in a number of situations.</p>
<p>Anyway, this wasn&#8217;t supposed to be a discussion of <code>partial</code> in general, but one problem I&#8217;ve hit with it when trying to partially apply a call to a Java static method. So, let&#8217;s implement our trivial <code>add</code> method in plain old Java:</p>
<pre class="brush: java;">
public class Functions {
    public static int add(int first, int second) {
        return first + second;
    }
}
</pre>
<p>Then try using <code>partial</code> as before:</p>
<pre class="brush: clojure;">
user=> (import com.xxx.yyy.Functions)
com.xxx.yyy.Functions
user=> (Functions/add 1 2)
3
user=> (def increment-by-two (partial Functions/add 1))
java.lang.Exception: Unable to find static field: add in class com.xxx.yyy.Functions (NO_SOURCE_FILE:3)
user=>
</pre>
<p>So it seems like the partial call can&#8217;t handle static calls in this situation. But what if I wrap the call in another function?</p>
<pre class="brush: clojure;">
user=> (defn java-add [arg1 arg2] (Functions/add arg1 arg2))
#'user/java-add
user=> (def increment-by-two (partial java-add 2))
#'user/increment-by-two
user=> (increment-by-two 10)
12
</pre>
<p>Which works. There is probably a reason why, but I can&#8217;t quite work it out right now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/06/19/clojure-partially-applied-functions-and-java-interop/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>In Clojure, Those Parenthesis Really Matter</title>
		<link>http://www.magpiebrain.com/2010/06/13/in-clojure-those-parenthesis-really-matter/</link>
		<comments>http://www.magpiebrain.com/2010/06/13/in-clojure-those-parenthesis-really-matter/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 18:13:27 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[clojure]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=836</guid>
		<description><![CDATA[Posted in the &#8220;I hope no-one else has to go through this&#8221; category in the hope that Google surfaces this for some other poor soul. Picture a rather trivial split function: (defn split [str delimiter] ((seq (.split str delimiter)))) Which helpfully spits out: java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn The issue here is the [...]]]></description>
			<content:encoded><![CDATA[<p>Posted in the &#8220;I hope no-one else has to go through this&#8221; category in the hope that Google surfaces this for some other poor soul.</p>
<p>Picture a rather trivial split function:</p>
<pre class="brush: clojure;">
(defn split [str delimiter]
  ((seq (.split str delimiter))))
</pre>
<p>Which helpfully spits out:</p>
<pre>
java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn
</pre>
<p>The issue here is the additional set of parentheses &#8211; a hang-over from a previous edit. Removing this fixed the trouble. These parentheses were causing Clojure to expect a function call&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/06/13/in-clojure-those-parenthesis-really-matter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>My Talk at QCon SF 2009</title>
		<link>http://www.magpiebrain.com/2010/03/12/my-talk-at-qcon-sf-2009/</link>
		<comments>http://www.magpiebrain.com/2010/03/12/my-talk-at-qcon-sf-2009/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 10:40:15 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[presentations]]></category>
		<category><![CDATA[qcon]]></category>
		<category><![CDATA[qconsf]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=826</guid>
		<description><![CDATA[The talk I did at QCon SF 2009 is now available at infoq. Only an MP3 download is available, otherwise you&#8217;ll have to stream it from the site &#8211; but you&#8217;ll be missing a lot, as the slides are better than hearing me drone on.]]></description>
			<content:encoded><![CDATA[<p>The talk I did at QCon SF 2009 is <a href="http://www.infoq.com/presentations/navigating-agile-rapids" title="Navigating The Rapids:Real-World Lessons in Adopting Agile">now available</a> at infoq. Only an MP3 download is available, otherwise you&#8217;ll have to stream it from the site &#8211; but you&#8217;ll be missing a lot, as the slides are better than hearing me drone on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/03/12/my-talk-at-qcon-sf-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QCon London</title>
		<link>http://www.magpiebrain.com/2010/02/16/qcon-london/</link>
		<comments>http://www.magpiebrain.com/2010/02/16/qcon-london/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 21:12:20 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[Build And Deployment]]></category>
		<category><![CDATA[presentations]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[qcon]]></category>
		<category><![CDATA[speaking]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=787</guid>
		<description><![CDATA[I&#8217;ve been invited to speak on colleague Chris Read&#8217;s track at QCon London this March. The track itself is chock full of a number of experienced proffesionals (including two ex-colleagues) so I fully intend to raise my game accordingly. We&#8217;re lucky enough to have Michael T. Nygard speaking too, author of perhaps the best book [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.magpiebrain.com/wp-content/uploads/2010/02/Screen-shot-2010-02-16-at-08.07.11.png"><img src="http://www.magpiebrain.com/wp-content/uploads/2010/02/Screen-shot-2010-02-16-at-08.07.11.png" alt="" title="QCon Logo" width="259" height="101" class="alignleft size-full wp-image-786" /></a> I&#8217;ve been invited to speak on colleague <a href="http://blog.chris-read.net/">Chris Read&#8217;s</a> track at <a href="http://qconlondon.com/">QCon London</a> this March. The track itself is chock full of a number of experienced proffesionals (including two ex-colleagues) so I fully intend to raise my game accordingly. We&#8217;re lucky enough to have Michael T. Nygard speaking too, author of perhaps the best book written for software developers in years in the form of <a href="http://www.pragprog.com/titles/mnee/release-it">Release It!</a></p>
<p>The track &#8211; &#8220;<a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=331">Dev and Ops &#8211; a Single Team</a>&#8221; &#8211; attempts to address many of the issues software professionals have in getting their software live. It will cover many aspects, both on the hardcore technical and on the softer people side. Hopefully it will provide lots of useful information you can take back to your own teams.</p>
<p>My talk &#8211; <a href="http://qconlondon.com/london-2010/presentation/From+Dev+to+Production%3A+Better+Living+through+Build+Pipelines+and+Teamwork">From Dev To Production</a>- will be giving an overview of build pipelines, and how they can be used to get the whole delivery team focused on the end objective &#8211; shipping quality software as quickly as possible. It draws on some of my recent writing on <a href="http://www.magpiebrain.com/category/development/build-and-deployment/build-and-deployment-patterns/">build patterns</a>, and a wealth of knowledge built up inside ThoughtWorks over the past few years.</p>
<p>My experience of QCon SF last year was excellent &#8211; I can thoroughly recommend it to any IT professional involved in shipping software. If you haven&#8217;t got your ticket already, <a href="https://secure.trifork.com/london-2010/registration/">go get them now</a> before the prices go up!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/02/16/qcon-london/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Struggling with Test Driven Clojure</title>
		<link>http://www.magpiebrain.com/2010/02/16/struggling-with-test-driven-clojure/</link>
		<comments>http://www.magpiebrain.com/2010/02/16/struggling-with-test-driven-clojure/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 20:56:50 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=790</guid>
		<description><![CDATA[I&#8217;ve recently been working on a Clojure application that I hope to open source soon. It&#8217;s been my first experience of using Clojure, and is almost certainly one of the most thought provking things I&#8217;ve done in a long while. One of the things that is still causing me issues is how to go about [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.magpiebrain.com/2010/02/16/struggling-with-test-driven-clojure/3383144624_0d3b5c53c9/" rel="attachment wp-att-789"><img src="http://www.magpiebrain.com/wp-content/uploads/2010/02/3383144624_0d3b5c53c9-150x150.jpg" alt="" title="Puzzled" width="150" height="150" class="alignright  size-thumbnail wp-image-789" /></a> I&#8217;ve recently been working on a Clojure application that I hope to open source soon. It&#8217;s been my first experience of using Clojure, and is almost certainly one of the most thought provking things I&#8217;ve done in a long while. One of the things that is still causing me issues is how to go about TDDing Clojure applications &#8211; or rather functional programs in general. </p>
<p>My natural inclination &#8211; for many reasons &#8211; is to use TDD as my process of choice for developing my code. Beyond its use as a design tool, it&#8217;s having a saftey net to catch me if I screw something up. It allows me to be a little more brave, and drastically reduces the cycle between changing some code and being happy that it works. I&#8217;m used to that saftey net &#8211; I feel lost without it.</p>
<p>Stuart Halloway said during his Clojure talk at Qcon SF that despite being a TDD fan he finds it hard to TDD in a new language, and I get exactly what he means. A big part of it is that you&#8217;re getting to grips with the idioms, capabilities, libraries and tools associated with your new language &#8211; and a lack of this knowledge is going to impact on your ability to write good tests, let alone worry about implementing them.</p>
<p>Typically, when learning a new language I try and write a small application that has a real world need. <a href="http://code.google.com/p/bigvisiblewall/">BigVisibleWall</a> was my attempt to learn Scala &#8211; but it had a real goal. With BigVisibleWall, as with my current Clojure project, I started by implementing the system by just writing the production code. I&#8217;m pushing the limits of my knowledge constantly, attempting to understand the size and shape of the solution space that I find myself in with this new tool. Once I got BigVisibleWall working with a small set of features, I broke it down and rewrote it TDD style &#8211; at that point, I had enough Scala (and I mean *just* enough) to be able to do this without it feeling like I was wading through treacle.</p>
<p>I consciously decided to follow the same pattern with my Clojure project. Code the main logic, get it running, then break it down and rewrite it piece by piece using TDD. But then I hit a problem &#8211; Scala and Java are similar enough languages that my programming style didn&#8217;t have to change much from one to the other. Therefore the way I structured the code and thought about TDD didn&#8217;t have to shift much. In both cases I was driving the design of an Object Oriented system. With Clojure though it wasn&#8217;t just the language which was different, it was so many of the underlying concepts were different. Put simply, I really don&#8217;t know where to begin.</p>
<p>My first instinct is to start decomposing functions, passing in stubs to the functions under test. But this just feels like I&#8217;m trying to shoehorn IOC-type patterns into a functional program. But what am I left with &#8211; testing large combinations of functions? That feels wrong too.</p>
<p>So what about you lot out there in blogland? Any other OO types trying to make the switch and encountering the same issues? Or any FP practitioners for whom TDD is second nature? Or does TDD just not fit with FP after all?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/02/16/struggling-with-test-driven-clojure/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Clojure on App Engine &#8211; my take</title>
		<link>http://www.magpiebrain.com/2010/02/14/clojure-on-app-engine-my-take/</link>
		<comments>http://www.magpiebrain.com/2010/02/14/clojure-on-app-engine-my-take/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 12:32:23 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[clojure]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=777</guid>
		<description><![CDATA[I&#8217;ve been working on a couple of spare time projects, both of which I hope to release more formally in the next few weeks. One of them involves development of a simple web application for deployment on Google App Engine. As part of the development, I had to modify an existing open source Clojure API [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a couple of spare time projects, both of which I hope to release more formally in the next few weeks. One of them involves development of a simple web application for deployment on <a href="http://code.google.com/appengine/">Google App Engine</a>. As part of the development, I had to modify an existing open source Clojure API &#8211; my changes are now available for all.</p>
<p><a href="http://github.com/duelinmarkers/appengine-clj"><code>appengine-clj</code></a> was written by ThoughtWorks colleague John Hume. It provides some Clojure-esque wrappers over Google App Engine&#8217;s user authentication and low level datastore API. John outlines his use of the library in a <a href="http://elhumidor.blogspot.com/2009/04/clojure-on-google-appengine.html">highly useful post</a> on using <a href="http://github.com/weavejester/compojure">Compojure</a> &#038; Clojure on the App Engine &#8211; it was this post which helped immensely in getting started myself.</p>
<p>There were a couple of minor issues with the latest version of John&#8217;s API which stopped me from being able to use it for my latest project &#8211; so I created a fork to make the changes I wanted. First, a general issue. I love projects which make checkout and build easy and bullet-proof. For me, that means check in the build tool &#038; all dependencies. I know this is a contentious point &#8211; I may well write a post on it later. The other issue is that since the 1.2 version of the SDK some of the APIs have changed a little, so I updated the datastore testing macro accordingly.</p>
<p>My Clojure skills are highly limited, and the modest modifications are probably botched, but nonetheless it seems to work. My fork can be found <a href="http://github.com/snewman/appengine-clj">on GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/02/14/clojure-on-app-engine-my-take/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Build Pattern: Chained Continuous Build</title>
		<link>http://www.magpiebrain.com/2010/01/24/build-pattern-chained-continuous-build/</link>
		<comments>http://www.magpiebrain.com/2010/01/24/build-pattern-chained-continuous-build/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 18:22:36 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[Build And Deployment Patterns]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[buildpattern]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[pattern]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=744</guid>
		<description><![CDATA[One of the problems quickly encountered when any new team adopts a Continuous Build is that builds become slow. Enforcing a Build Time Limit can help, but ultimately if all of your Continuous Build runs as one big monolithic block, there are limits to what you can do to decrease build times. One of the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.magpiebrain.com/wp-content/uploads/2010/01/pipeline-flickr-Stuck-in-Customs.jpg"><img class="alignleft size-thumbnail wp-image-694" title="The Steam Pipeline" src="http://www.magpiebrain.com/wp-content/uploads/2010/01/pipeline-flickr-Stuck-in-Customs-150x150.jpg" alt="Pipeline from Flickr user Stuck in Customs" width="150" height="150" /></a> One of the problems quickly encountered when any new team adopts a Continuous Build is that builds become slow. Enforcing a <a title="Magpiebrain: Build Pattern: Build Time Limit" href="http://www.magpiebrain.com/2010/01/16/build-pattern-build-time-limit/">Build Time Limit</a> can help, but ultimately if all of your Continuous Build runs as one big monolithic block, there are limits to what you can do to decrease build times.</p>
<p>One of the main issues is that you don&#8217;t get fast feedback to tell you when there is an issue &#8211; by breaking up a monolithic build you can gain fast feedback without reducing code coverage, and often without any complex setup.</p>
<p>In a <strong>Chained Continuous Build</strong>, multiple build stages are chained together in a flow. The goal is for the earlier stages to provide the fastest feedback possible, so that build breakages can be detected early. For example, a simple flow might first compile the software and run the unit tests, with the next stage running the slower end-to-end tests.</p>
<p><a href="http://www.magpiebrain.com/wp-content/uploads/2010/01/Simple.gif"><img class="aligncenter size-full wp-image-748" title="Simple Build Chain" src="http://www.magpiebrain.com/wp-content/uploads/2010/01/Simple.gif" alt="" width="294" height="94" /></a></p>
<p>With the chain, a downstream stage only runs if the previous stage passed &#8211; so in the above example, the end-to-end stage only runs if the build-and-test stage passes. </p>
<h3>Handling Breaks</h3>
<p>As with a Continuous Build you need to have a clear escalation process by which the whole team understands what to do in case of a break. Most teams I have worked with tend to stick to the rule of downing tools to fix the build if any part of the Continuous Build is red &#8211; which is strongly recommended. It is important that if you do decide to split your continuous build into a chain that you don&#8217;t let the team ignore builds that happen further along the chain.</p>
<h3>Build Artifacts Once vs Rebuild</h3>
<p>It is strongly suggested that you build the required artifacts once, and pass them along the chain. Rebuilding artifacts takes time &#8211; and the whole point of a chained build is to improve feedback. Additionally getting into the habit of building an artifact once, and once only, will help when you start considering creating a proper Build Pipeline (see below).</p>
<h3>And Build Pipelines</h3>
<p>Note that a chained build is not necessarily the same thing as a Build Pipeline. A Chained Continuous Build simply represents one or more Continuous Builds in series, whereas a Build Pipeline fully models all the stages a software artifact moves from development right through to production. One or more Chained Continuous Builds may form part of a Build Pipeline, and a simplistic Build Pipeline might not represent anything other than Chained Continuous Builds, but Build Pipelines will often incorporate activities more varied than compilation or test running.</p>
<h3>Fast Feedback vs Fast Total Build Time</h3>
<p>One thing to note is that by breaking a big build up into smaller sections to improve fast feedback, counterintuitively you may well end up increasing overall build time. The time to build and pass artifacts from one stage to another adds time, as does dispatching calls to build processes further down the chain. This balance has to be considered &#8211; consider being conservative in the splits you make, and always keep an eye on the total duration of your build chain.</p>
<h3>Tool Support</h3>
<p>Tooling can be complex. Simple straight-line chains can be relatively easily build using most continuous build systems. For example a common approach is to have one build check in some artifact which is the trigger point for another Continuos Build to run. Such approaches have the downside that the chain isn&#8217;t explicitly modelled, and reporting of the current state of the chain ends up having to be jury rigged, typically through custom dashboards. More complex still is dealing with branching chains.</p>
<p>Continuous Build systems have got more mature of late, with many of them supporting simple Chained Continuous Builds out of the box. <a title="TeamCity Build Chains and Enhanced Build Dependencies support" href="http://www.jetbrains.com/teamcity/features/continuous_integration.html#Build_Chains_and_Enhanced_Build_Dependencies">TeamCity</a>, <a title="Hudson Downstream-Ext Plugin" href="http://wiki.hudson-ci.org/display/HUDSON/Downstream-Ext+Plugin">Hudson</a> and <a title="Cruise Features" href="http://www.thoughtworks-studios.com/cruise-release-management/features-benefits">Cruise</a> and others all have some form of (varying) support. Cruise probably has the best support for running stages in parallel (caveat: Cruise is written by ThoughtWorks, the company I currently work for), and has some of the better support for visualising the chains, but given the way all of these tools are moving expect support in this area to get much better over time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/01/24/build-pattern-chained-continuous-build/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Organisation Antipattern: Chase The Ball</title>
		<link>http://www.magpiebrain.com/2010/01/17/organsiation-antipattern-chase-the-ball/</link>
		<comments>http://www.magpiebrain.com/2010/01/17/organsiation-antipattern-chase-the-ball/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 14:57:58 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[antipatterns]]></category>
		<category><![CDATA[organisations]]></category>
		<category><![CDATA[teams]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=681</guid>
		<description><![CDATA[Have you ever watched young children play football (of Soccer for our Atlantic cousins)? During the game, you can be certain of one thing &#8211; most of the team on both sides will be doing nothing but chasing the ball. There is no thought about the bigger picture, no tactical decision making (let alone anything [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-680" href="http://www.magpiebrain.com/2010/01/17/organsiation-antipattern-chase-the-ball/football/"><img class="alignleft size-thumbnail wp-image-680" title="Kids Football" src="http://www.magpiebrain.com/wp-content/uploads/2010/01/football-150x150.jpg" alt="Football - from flickr user mosilager" width="150" height="150" /></a>Have you ever watched young children play football (of Soccer for our Atlantic cousins)? During the game, you can be certain of one thing &#8211; most of the team on both sides will be doing nothing but chasing the ball. There is no thought about the bigger picture, no tactical decision making (let alone anything as grand as strategy). they only thought on everyone&#8217;s minds is that &#8220;We need to get the ball&#8221;.</p>
<p>This thinking in children is understandable. Less clear can be the basis for this kind of behaviour within an organisation.</p>
<p>Typically, the &#8216;lets drop everything and Chase The Ball&#8217; mentality comes from organisations which are primarily reactive, rather than proactive. Companies which exist almost always in crisis mode typically have a reactive attitude &#8211; working in teams like this can feel like you&#8217;re being buffeted by forces outside of your control, running from one disaster to another, never making progress towards where you need to go.</p>
<p>Small organisations that have got big often never get out of there reactive, firefighting mentality. All that happens is that more people are fighting the same fire.</p>
<p>To be clear I&#8217;m not talking about the problem being a single focus. I&#8217;m talking about a team or organisation fixating on a single focus which isn&#8217;t actually aligned with the longer term objectives. A bunch of kids chasing the ball need to think about winning the game, not getting the ball. Likewise an organisation needs to have clear line of sight to what its goals are, and always understand how what they are doing now gets them to where they want to go.</p>
<p>There will always be urgent, short term things that need to be addressed. The important thing is that they are dealt with in proportion, without loosing sight of the overall objectives. Ring-fence team members (making sure they aren&#8217;t always the same people) to Chase The Ball, and leave the larger organisation to focus on winning the game, or better yet winning the league.</p>
<p class="update">Update: Fixed typo, thanks Ben and Julian!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/01/17/organsiation-antipattern-chase-the-ball/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build Pattern: Build Time Limit</title>
		<link>http://www.magpiebrain.com/2010/01/16/build-pattern-build-time-limit/</link>
		<comments>http://www.magpiebrain.com/2010/01/16/build-pattern-build-time-limit/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 21:31:15 +0000</pubDate>
		<dc:creator>Sam Newman</dc:creator>
				<category><![CDATA[Build And Deployment Patterns]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[team]]></category>

		<guid isPermaLink="false">http://www.magpiebrain.com/?p=689</guid>
		<description><![CDATA[Anyone who has worked in a team which uses a Continuous Build inevitably starts to learn about the cost of a long running build: More time between checkin and a report of a failure Higher chance of Continuous Build containing multiple checkins, increasing the chance of an integration break and complicating rollback Fixing a build [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-688" href="http://www.magpiebrain.com/2010/01/16/build-pattern-build-time-limit/clock-flickr-laffy4k/"><img class="alignright size-thumbnail wp-image-688" title="Clock" src="http://www.magpiebrain.com/wp-content/uploads/2010/01/clock-flickr-laffy4k-150x150.jpg" alt="Clock - from flickr user laffy4k" width="150" height="150" /></a> Anyone who has worked in a team which uses a Continuous Build inevitably starts to learn about the cost of a long running build:</p>
<ul>
<li>More time between checkin and a report of a failure</li>
<li>Higher chance of Continuous Build containing multiple checkins, increasing the chance of an integration break and complicating rollback</li>
<li>Fixing a build related to a checkin made much earlier decreases productivity, leading to a reduction in productivity</li>
</ul>
<p>There are other &#8216;build&#8217; times to be aware of. A long <a title="magpiebrain: Build Pattern: Checkin Gate" href="http://www.magpiebrain.com/2007/01/29/build-pattern-checkin-gate/">Checkin Gate</a> build leads to an increased chance of someone else checking in before you, increasing the chance of an integration break when you do checkin. It also disrupts the developers normal flow &#8211; they cannot easily work on new code, so effectively have to down tools waiting for the Checkin Gate has finished. You also need to consider the time taken to run a single test &#8211; be it a small-scoped unit test, or a larger end to end test.</p>
<p>No matter what the build is, a long build interrupts programmer flow, decreasing focus, and therefore decreasing productivity.</p>
<h3>Different Builds, Different Limits</h3>
<p>As a team, you should decide on acceptable <strong>Build Time Limit</strong> for each &#8216;build&#8217; &#8211; for example individual tests, Checkin Gates, and stages in your continuous build. You may even consider failing these builds if those time limits fail. Setting the Build Time Limit at the right level &#8211; and keeping it there &#8211; will help keep productivity high.</p>
<p>Different builds get run with different frequencies. The more often a build is run, the faster it needs to be. Experience suggests the following time limits:</p>
<ul>
<li>Single small-scoped unit test &#8211; sub-second</li>
<li>End-to-end test &#8211; a few seconds</li>
<li>Checkin Gate &#8211; 30 seconds to a couple of minutes at most</li>
<li>Continuous Build &#8211; a handful of minutes</li>
</ul>
<p>When your Continuous Build is part of a larger Build Pipeline, you may find it useful to set Build Time Limits for each stage in the pipeline. One might argue that enforcing Build Time Limits for each stage of a Build Pipeline &#8211; manual or automated &#8211; may be overkill, but having some reporting of when a limit is exceeded will help directly highlight bottlenecks in creating production deployable software.</p>
<h3>Team Ownership</h3>
<p>Teams must take ownership of ensuring that the Build Time Limit is enforced. Further, they should always look for opportunities to reduce them further. Any decision to increase any Build Time Limit should be taken by the whole team &#8211; likewise any decrease in a Built Time Limit with decreases test coverage should be agreed with all. Everyone should be empowered however to look for quick wins.</p>
<p>Some teams find the need for a Build Tzar/Build Cop role &#8211; someone who is in charge of the health of the build. I consider such roles as being short term measures only, and should certainly be considered an anti-pattern if they exist for any length of time. At the extreme end of this spectrum is the dedicated build team. Empowering the whole team is key.</p>
<h3>Making Things Faster</h3>
<p>There are a number of ways of making individual tests fast, which will depend both on the nature of the technology being used and the way it is being used. Consider making a Checkin Gate fast using a <a title="magpiebrain: Build Pattern: Movable Checkin Gate" href="http://www.magpiebrain.com/2010/01/10/build-pattern-movable-checkin-gate/">Movable Checkin Gate</a>. Long Continuous Build times can be mitigated through the use of a <a href="http://www.magpiebrain.com/2010/01/24/build-pattern-chained-continuous-build/" title="Magpiebrain - Build Pattern: Chained Continuous Build">Chained Continuous Build</a>, perhaps as part of a larger Build Pipeline. </p>
<p>You may also want to simply remove tests that are slow but provide little coverage. Often, it may even be the case that slow running tests represent a performance issue in the system itself.</p>
<p>Some teams have also shown significant speed improvements by using the right hardware &#8211; such as faster CPUs, RAM disks or SSD drives. However simply throwing hardware at the problem can help speed a Continuous Build up, but this does little to affect the build time on local development machines &#8211; a situation where your continuous build is faster than your local development build is the opposite of what you want.</p>
<h3>Further Reading</h3>
<p>For more concrete evidence on how build times can influence the productivity of teams, <a href="http://www.grahambrooks.com/">Graham Brook&#8217;s</a> paper for Agile 2008, <a href="http://portal.acm.org/citation.cfm?id=1443512">Team Pace &#8211; Keeping Build Times Down</a>, details experiences of working with two different teams and the impact of long (and short) build times on the development team. Thanks also go to Graham for reviewing an earlier draft of this article.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.magpiebrain.com/2010/01/16/build-pattern-build-time-limit/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
