<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>The Inquisitive Coder - Davy Brion's Blog</title>
	
	<link>http://davybrion.com/blog</link>
	<description>Trying to walk that thin line between intelligence and ignorance</description>
	<lastBuildDate>Sun, 05 Jul 2009 19:45:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/davybrion" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Protecting Your Application From Remote Problems</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/ovef-tQAeng/</link>
		<comments>http://davybrion.com/blog/2009/07/protecting-your-application-from-remote-problems/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 19:45:41 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Aspect Oriented Programming]]></category>
		<category><![CDATA[Castle Windsor]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1443</guid>
		<description><![CDATA[If you have a web application which communicates with a remote service, it&#8217;s important to protect that web application from any problems the remote service might be dealing with.  For instance, if the remote service goes down (for whatever reason) you really don&#8217;t want your application to keep making calls to this service.  [...]]]></description>
			<content:encoded><![CDATA[<p>If you have a web application which communicates with a remote service, it&#8217;s important to protect that web application from any problems the remote service might be dealing with.  For instance, if the remote service goes down (for whatever reason) you really don&#8217;t want your application to keep making calls to this service.  These failing calls increase the load on the service, which is already having problems, and will also block your threads which takes away resources from your application to deal with other requests.  One pattern which is very suitable to reduce the problems for this situation is the <a href="http://davybrion.com/blog/2008/05/the-circuit-breaker/">Circuit Breaker</a> (read that unless you&#8217;re familiar with the circuit breaker).</p>
<p>The biggest issue i have with my previous implementation is that it required you to call it manually to protect potentially risky calls.  I don&#8217;t like having to call my circuit breaker whenever i want to make a service call because as a consumer of a service proxy, i shouldn&#8217;t even know about the circuit breaker.  I also don&#8217;t want any coupling between my service proxy and the actual circuit breaker.  Sounds like a good candidate for some AOP magic, right? </p>
<p>We&#8217;re going to use Castle Windsor&#8217;s Interceptors to make this work.  First, the implementation of the CircuitBreaker class:</p>
<p><code></p>
<style type="text/css">
.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
</style>
<div class="cf">
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">class</span> <span class="cb2">CircuitBreaker</span> : <span class="cb2">IInterceptor</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">readonly</span> <span class="cb1">object</span> monitor = <span class="cb1">new</span> <span class="cb1">object</span>();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb2">CircuitBreakerState</span> state;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">int</span> failures;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">int</span> threshold;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb2">TimeSpan</span> timeout;</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> CircuitBreaker(<span class="cb1">int</span> threshold, <span class="cb2">TimeSpan</span> timeout)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">this</span>.threshold = threshold;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">this</span>.timeout = timeout;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MoveToClosedState();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">void</span> Intercept(<span class="cb2">IInvocation</span> invocation)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">using</span> (<span class="cb2">TimedLock</span>.Lock(monitor))</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; state.ProtectedCodeIsAboutToBeCalled();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">try</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; invocation.Proceed();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">catch</span> (<span class="cb2">Exception</span> e)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">using</span> (<span class="cb2">TimedLock</span>.Lock(monitor))</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; failures++;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; state.ActUponException(e);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">throw</span>;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">using</span> (<span class="cb2">TimedLock</span>.Lock(monitor))</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; state.ProtectedCodeHasBeenCalled();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">void</span> MoveToClosedState()</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; state = <span class="cb1">new</span> <span class="cb2">ClosedState</span>(<span class="cb1">this</span>);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">void</span> MoveToOpenState()</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; state = <span class="cb1">new</span> <span class="cb2">OpenState</span>(<span class="cb1">this</span>);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">void</span> MoveToHalfOpenState()</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; state = <span class="cb1">new</span> <span class="cb2">HalfOpenState</span>(<span class="cb1">this</span>);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">void</span> ResetFailureCount()</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; failures = 0;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">bool</span> ThresholdReached()</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">return</span> failures &gt;= threshold;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">abstract</span> <span class="cb1">class</span> <span class="cb2">CircuitBreakerState</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">protected</span> <span class="cb1">readonly</span> <span class="cb2">CircuitBreaker</span> circuitBreaker;</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">protected</span> CircuitBreakerState(<span class="cb2">CircuitBreaker</span> circuitBreaker)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">this</span>.circuitBreaker = circuitBreaker;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">virtual</span> <span class="cb1">void</span> ProtectedCodeIsAboutToBeCalled() { }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">virtual</span> <span class="cb1">void</span> ProtectedCodeHasBeenCalled() { }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">virtual</span> <span class="cb1">void</span> ActUponException(<span class="cb2">Exception</span> e) { }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">class</span> <span class="cb2">ClosedState</span> : <span class="cb2">CircuitBreakerState</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> ClosedState(<span class="cb2">CircuitBreaker</span> circuitBreaker)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; : <span class="cb1">base</span>(circuitBreaker)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; circuitBreaker.ResetFailureCount();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">override</span> <span class="cb1">void</span> ActUponException(<span class="cb2">Exception</span> e)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (circuitBreaker.ThresholdReached()) circuitBreaker.MoveToOpenState();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">class</span> <span class="cb2">OpenState</span> : <span class="cb2">CircuitBreakerState</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">readonly</span> <span class="cb2">Timer</span> timer;</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> OpenState(<span class="cb2">CircuitBreaker</span> circuitBreaker)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; : <span class="cb1">base</span>(circuitBreaker)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; timer = <span class="cb1">new</span> <span class="cb2">Timer</span>(circuitBreaker.timeout.TotalMilliseconds);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; timer.Elapsed += TimeoutHasBeenReached;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; timer.AutoReset = <span class="cb1">false</span>;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; timer.Start();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">void</span> TimeoutHasBeenReached(<span class="cb1">object</span> sender, <span class="cb2">ElapsedEventArgs</span> e)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; circuitBreaker.MoveToHalfOpenState();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">override</span> <span class="cb1">void</span> ProtectedCodeIsAboutToBeCalled()</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">throw</span> <span class="cb1">new</span> <span class="cb2">OpenCircuitException</span>();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">class</span> <span class="cb2">HalfOpenState</span> : <span class="cb2">CircuitBreakerState</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> HalfOpenState(<span class="cb2">CircuitBreaker</span> circuitBreaker) : <span class="cb1">base</span>(circuitBreaker) { }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">override</span> <span class="cb1">void</span> ActUponException(<span class="cb2">Exception</span> e)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; circuitBreaker.MoveToOpenState();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">override</span> <span class="cb1">void</span> ProtectedCodeHasBeenCalled()</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; circuitBreaker.MoveToClosedState();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
</div>
<p></code></p>
<p>Notice how the CircuitBreaker class implements Windsor&#8217;s IInterceptor interface.  The Intercept method will be called by Windsor whenever we try to call a method from a protected component.  Within the Intercept method we can add the necessary logic to apply the Circuit Breaker pattern to the code that was originally called. </p>
<p>Now we just need to configure the Windsor IOC container to apply this bit of AOP magic for us.</p>
<p>First, we register the CircuitBreaker with the container:</p>
<p><code></p>
<style type="text/css">
.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: #2b91af; }
.cb2 { color: #a31515; }
.cb3 { color: blue; }
</style>
<div class="cf">
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; container.Register(<span class="cb1">Component</span>.For&lt;<span class="cb1">CircuitBreaker</span>&gt;().LifeStyle.Singleton</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; .Named(<span class="cb2">&quot;serviceProxyCircuitBreaker&quot;</span>)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; .DependsOn(<span class="cb3">new</span> <span class="cb1">Hashtable</span> { { <span class="cb2">&quot;threshold&quot;</span>, 5 }, { <span class="cb2">&quot;timeout&quot;</span>, <span class="cb1">TimeSpan</span>.FromMinutes(5) } }));</p>
</div>
<p></code></p>
<p>Notice that we register the CircuitBreaker implementation with a Singleton lifestyle, a custom name and the required constructor parameters to create an instance of the CircuitBreaker.</p>
<p>Then we register our service proxy:</p>
<p><code></p>
<style type="text/css">
.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: #2b91af; }
.cb2 { color: #a31515; }
</style>
<div class="cf">
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; container.Register(<span class="cb1">Component</span>.For&lt;<span class="cb1">IServiceProxy</span>&gt;().ImplementedBy&lt;<span class="cb1">ServiceProxy</span>&gt;().LifeStyle.Transient</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .Interceptors(<span class="cb1">InterceptorReference</span>.ForKey(<span class="cb2">&quot;serviceProxyCircuitBreaker&quot;</span>)).Anywhere);</p>
</div>
<p></code></p>
<p>Notice how we registered the service proxy as a transient component, while referencing the singleton CircuitBreaker interceptor.  This means that each resolved instance of our service proxy will be protected by the same CircuitBreaker instance.  If you have multiple services that you want to protect, simply register multiple CircuitBreakers with different keys and link each service you want to protect with the correct CircuitBreaker key.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F07%2Fprotecting-your-application-from-remote-problems%2F&amp;linkname=Protecting%20Your%20Application%20From%20Remote%20Problems" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/j5EwU8u2BbCJlkp2bFBxtYZ1F70/0/da"><img src="http://feedads.g.doubleclick.net/~a/j5EwU8u2BbCJlkp2bFBxtYZ1F70/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/j5EwU8u2BbCJlkp2bFBxtYZ1F70/1/da"><img src="http://feedads.g.doubleclick.net/~a/j5EwU8u2BbCJlkp2bFBxtYZ1F70/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=ovef-tQAeng:O6Hm-T3SWjQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=ovef-tQAeng:O6Hm-T3SWjQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=ovef-tQAeng:O6Hm-T3SWjQ:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/ovef-tQAeng" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/07/protecting-your-application-from-remote-problems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/07/protecting-your-application-from-remote-problems/</feedburner:origLink></item>
		<item>
		<title>Save Some Time With The Right Testrunner</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/AG3W6VWzqA8/</link>
		<comments>http://davybrion.com/blog/2009/07/save-some-time-with-the-right-testrunner/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 08:04:27 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1439</guid>
		<description><![CDATA[If you&#8217;re running your tests multiple times throughout the day, it&#8217;s in your best interest to keep those testruns as fast as possible.  We have a solution with 2 test projects.  The first testproject contains 2700 regular tests that don&#8217;t use any external resources so they should be very fast.  The second [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re running your tests multiple times throughout the day, it&#8217;s in your best interest to keep those testruns as fast as possible.  We have a solution with 2 test projects.  The first testproject contains 2700 regular tests that don&#8217;t use any external resources so they should be very fast.  The second testproject contains 1200 database tests (you do write tests for your queries, right?) which is a little bit slower, as is to be expected.</p>
<p>The problem is that with Resharper&#8217;s testrunner, running the database tests actually takes less time than running the &#8216;fast&#8217; tests.  The 1200 database tests take 1m14 seconds to run.  The 2700 in memory tests take 1m20 seconds to run&#8230; so that&#8217;s almost 3 minutes of waiting time whenever you run the entire testsuite.</p>
<p>Just out of curiosity, i ran all of the tests with TestDriven.NET to see how much faster it would be&#8230; The 1200 database tests only took about 45 seconds, and the 2700 in memory tests only took 28 seconds to run.  Running the entire testsuite with TestDriven.NET actually takes less than half the time it takes with Resharper&#8217;s testrunner&#8230; </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F07%2Fsave-some-time-with-the-right-testrunner%2F&amp;linkname=Save%20Some%20Time%20With%20The%20Right%20Testrunner" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/1-HvnbTZU4XkTlJ5zLCU6OOHiwA/0/da"><img src="http://feedads.g.doubleclick.net/~a/1-HvnbTZU4XkTlJ5zLCU6OOHiwA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/1-HvnbTZU4XkTlJ5zLCU6OOHiwA/1/da"><img src="http://feedads.g.doubleclick.net/~a/1-HvnbTZU4XkTlJ5zLCU6OOHiwA/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=AG3W6VWzqA8:upsSdUsA8j0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=AG3W6VWzqA8:upsSdUsA8j0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=AG3W6VWzqA8:upsSdUsA8j0:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/AG3W6VWzqA8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/07/save-some-time-with-the-right-testrunner/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/07/save-some-time-with-the-right-testrunner/</feedburner:origLink></item>
		<item>
		<title>Avoid Using NHibernate With NUnit 2.4.6</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/k8HY8F9Ukbs/</link>
		<comments>http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 17:35:42 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1432</guid>
		<description><![CDATA[We just spent about 2 hours trying to find out why our NHibernate tests were about 10x slower on our build server than they were on our local machines.  I had noticed lately that the build for one of our projects was taking longer and longer but i hadn&#8217;t really timed the difference.  [...]]]></description>
			<content:encoded><![CDATA[<p>We just spent about 2 hours trying to find out why our NHibernate tests were about 10x slower on our build server than they were on our local machines.  I had noticed lately that the build for one of our projects was taking longer and longer but i hadn&#8217;t really timed the difference.  This project has about 1200 tests that use NHibernate and they run in about 45-60 seconds on my local machine.  It turns out they took around 15 <strong>minutes</strong> on the buildserver when running them through TeamCity.</p>
<p>I logged into the buildserver and ran the tests manually using nunit&#8217;s console runner (with an NUnit-2.4.7 build that i happened to have installed somewhere on the machine) and they only took about 45 seconds.  After a lot of guesswork and screwing around, it turned out that we never modified our base build script (why yes, i do believe in build script inheritance) to use a newer version of NUnit.  We set up the buildserver about 1 year ago, and at that time, the latest stable NUnit version that TeamCity supported was NUnit 2.4.6.  Our base build script was still referring to NUnit 2.4.6, which apparently <a href="http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/nhibernate-nunit-2-4-6-and-log4net">sets log4net to use debug level logging</a>.  Now, NHibernate logs a huge amount of information at the debug level, so this turned out to slow down all of our builds that had NHibernate tests.</p>
<p>We changed the the 2.4.6 version in our script to 2.4.7 and the build time of this particular project decreased from around 50 minutes to about 35 minutes.  Yes, that&#8217;s still a lot but this is a huge project with a lot of legacy tests and the entire build process is pretty complex.  Other projects went from build times from around 7 minutes to about 2 minutes.</p>
<p>That&#8217;s a pretty nice improvement for simply changing a &#8220;6&#8243; to a &#8220;7&#8243; <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F06%2Favoid-using-nhibernate-with-nunit-2-4-6%2F&amp;linkname=Avoid%20Using%20NHibernate%20With%20NUnit%202.4.6" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/npmMMbFH0X1ipbdcwKbbQns4pqw/0/da"><img src="http://feedads.g.doubleclick.net/~a/npmMMbFH0X1ipbdcwKbbQns4pqw/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/npmMMbFH0X1ipbdcwKbbQns4pqw/1/da"><img src="http://feedads.g.doubleclick.net/~a/npmMMbFH0X1ipbdcwKbbQns4pqw/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=k8HY8F9Ukbs:4ur351XKdss:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=k8HY8F9Ukbs:4ur351XKdss:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=k8HY8F9Ukbs:4ur351XKdss:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/k8HY8F9Ukbs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/</feedburner:origLink></item>
		<item>
		<title>Surface Development For Belgian TV</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/CV8Ofg6D3Xk/</link>
		<comments>http://davybrion.com/blog/2009/06/surface-development-for-belgian-tv/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 12:20:48 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1422</guid>
		<description><![CDATA[Some of my coworkers recently developed 2 Surface applications for VTM, one of the commercial Belgian TV channels. This is one of the few high-profile usages of Microsoft&#8217;s Surface in Belgium so far.  Be sure to check out the videos on our company website.
]]></description>
			<content:encoded><![CDATA[<p>Some of my coworkers recently developed 2 <a href="http://www.microsoft.com/surface/">Surface</a> applications for <a href="http://www.vtm.be/">VTM</a>, one of the commercial Belgian TV channels. This is one of the few high-profile usages of Microsoft&#8217;s Surface in Belgium so far.  Be sure to check out the videos on our <a href="http://www.itemsolutions.com/home">company website</a>.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F06%2Fsurface-development-for-belgian-tv%2F&amp;linkname=Surface%20Development%20For%20Belgian%20TV" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/crrZmQB0XoNR4NfZufeY8p8JHnQ/0/da"><img src="http://feedads.g.doubleclick.net/~a/crrZmQB0XoNR4NfZufeY8p8JHnQ/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/crrZmQB0XoNR4NfZufeY8p8JHnQ/1/da"><img src="http://feedads.g.doubleclick.net/~a/crrZmQB0XoNR4NfZufeY8p8JHnQ/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=CV8Ofg6D3Xk:_IfLKwQXQzQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=CV8Ofg6D3Xk:_IfLKwQXQzQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=CV8Ofg6D3Xk:_IfLKwQXQzQ:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/CV8Ofg6D3Xk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/06/surface-development-for-belgian-tv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/06/surface-development-for-belgian-tv/</feedburner:origLink></item>
		<item>
		<title>And We’re Back</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/p4Y70hVJdls/</link>
		<comments>http://davybrion.com/blog/2009/06/and-were-back/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 12:20:02 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Off Topic]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1427</guid>
		<description><![CDATA[I got back from the Dominican Republic yesterday morning so i just wanted to post a short &#8216;review&#8217; of the trip.  Getting there took a looong time, because our plane first stopped in Cuba where we had to wait for another hour before we flew into Punta Cana.  Unfortunately, we weren&#8217;t allowed to [...]]]></description>
			<content:encoded><![CDATA[<p>I got back from the Dominican Republic yesterday morning so i just wanted to post a short &#8216;review&#8217; of the trip.  Getting there took a looong time, because our plane first stopped in Cuba where we had to wait for another hour before we flew into Punta Cana.  Unfortunately, we weren&#8217;t allowed to get off the plane for a short time which kinda sucks after 10 hours of flying.  The little bit of Cuba i did get to see (through the window) did look pretty nice though.  So after 13 hours we finally landed at Punta Cana&#8217;s airport and then we had to take a 2 hour bus ride to get to our <a href="http://www.iberostar.com/EN/Bayahibe-hotels/Iberostar-Hacienda-Dominicus_3_73.html">hotel</a>.</p>
<p>The hotel was great.  Big, nice rooms.  Lots of restaurants (4 plus a general buffet as well).  Great pool, including a nice bar.  Fantastic beach, also with a bar obviously.  Plenty of activities and a few shops as well.  If you really want to, you could have a pretty good time without even leaving the resort.</p>
<p>But that would be a bit of a shame because the country has so much more to offer than beautiful resorts.  I went on two excursions while i was there.  The first one was a snorkeling trip which was great.  It was basically a whole day on a boat going along the Caribbean coastline, which in itself is already a sight to behold.  Then there were 2 snorkeling sessions, one before noon, and one in the afternoon.  For lunch, we went to the <a href="http://en.wikipedia.org/wiki/Saona_Island">Saona island</a> which you may know better as the Bounty Island (used in the commercials) to have a barbecue plus some relaxing on the beach.  We also spent some time in a &#8216;natural swimming pool&#8217; which is located within the sea on a huge sandbank (which was the result of a hurricane a few years back, as i&#8217;ve been told).  It really is mindblowing to stand up in the middle of the ocean, with the water only reaching up to your waist. </p>
<p>The second excursion was a truck safari from the southern part of the island to the north side.  I&#8217;d definitely recommend doing this because the sights you see along the way are unbelievably beautiful.  And you don&#8217;t just spend the whole time in the truck either.  We stopped along a sugar cane field and tried real sugar from a sugar cane.  We also visited some people in the country side where we tried fresh coffee (from beans that had finished roasting in the sun just a few days ago), fresh cocoa (both in powder form after non-industrial processing as well as directly from the fruit), fresh Creole pine apple, coconuts, <a href="http://en.wikipedia.org/wiki/Mama_Juana">Mama Juana</a> and other things as well.  We had lunch on some ranch in the mountains (seeing large palm trees on top of high mountains is pretty cool as well) and after that we did some horseback riding.  We also visited a tiny school (with only 2 classrooms) and a big church in Higuey which is apparently pretty famous.  In the afternoon we stopped along a beach in the north side of the island (with the Atlantic ocean instead of the Carribean sea).  We definitely saw a lot of beautiful things during this excursion.  Funny side story: some British tourists that were also on the truck brought notepads and pens for the poor children we&#8217;d meet along the way.  During one of our walks, they gave them to two kids who were sitting in front of their house.  What these tourists didn&#8217;t realize was that those kids were sitting in front of a very nice house which actually had a beautiful pool in the backyard.  Good thing these poor kids now also have notepads and pens <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Combining these excursions with a lot of relaxing at the beach definitely makes for a great trip.  I&#8217;m not really a going-to-the-beach-kinda-guy but the Bahayibe beach and the Carribean Sea are just too nice to pass up on.  And the water is just incredible&#8230; it&#8217;s crystal clear, it&#8217;s very warm, and occasionally you&#8217;ll see a bunch of colorful fish swim by or even around you.</p>
<p>The one downside to the trip was that there was hardly anything to do at night where we were.  The northern side apparently has a lot more going on at night (it&#8217;s only normal with all the mass-tourism over there) but on the southern side there&#8217;s really not much to do outside of what&#8217;s going on in your resort.  I was there with my best friend so we were hoping for some interesting bars to go to at night, but we mostly stuck to the lobby bar in the resort for a lack of anything better.  You could just go to local towns and visit the bars over there but that&#8217;s not really recommended unless you&#8217;re with a reasonably-sized group to avoid trouble.  </p>
<p>But apart from that, everything was great and i&#8217;d definitely recommend it to anyone.  And after all of that, we spent another 9 hours on a plane to land in Brussels with pouring rain and pretty chilly weather *Sigh*.</p>
<p>I still have to go through a couple hundred blog posts that i missed, a shitload of email and some other stuff i have to do as well.  I&#8217;ll start posting and coding again in the next couple of days though <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F06%2Fand-were-back%2F&amp;linkname=And%20We%26%238217%3Bre%20Back" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/5MSeL8wlaJWLPTGOgLRwneqsiTc/0/da"><img src="http://feedads.g.doubleclick.net/~a/5MSeL8wlaJWLPTGOgLRwneqsiTc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/5MSeL8wlaJWLPTGOgLRwneqsiTc/1/da"><img src="http://feedads.g.doubleclick.net/~a/5MSeL8wlaJWLPTGOgLRwneqsiTc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=p4Y70hVJdls:ZluTBC7tp-8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=p4Y70hVJdls:ZluTBC7tp-8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=p4Y70hVJdls:ZluTBC7tp-8:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/p4Y70hVJdls" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/06/and-were-back/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/06/and-were-back/</feedburner:origLink></item>
		<item>
		<title>Time For A Much Needed Break</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/qLsS5w1hg4I/</link>
		<comments>http://davybrion.com/blog/2009/06/time-for-a-much-needed-break/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 19:55:37 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Off Topic]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1415</guid>
		<description><![CDATA[As you have probably noticed, i haven&#8217;t been very active lately.  Mostly because of some situations in my personal life lately which took up a lot of my spare time.  Because of this, i haven&#8217;t been posting as much as i used to, nor did i contribute anything to NHibernate in the past [...]]]></description>
			<content:encoded><![CDATA[<p>As you have probably noticed, i haven&#8217;t been very active lately.  Mostly because of some situations in my personal life lately which took up a lot of my spare time.  Because of this, i haven&#8217;t been posting as much as i used to, nor did i contribute anything to NHibernate in the past couple of weeks.  Luckily for me, i&#8217;m leaving for a trip to the Dominican Republic in a couple of days where i intend to explore the limits of the concept &#8220;relaxation&#8221;.  As much as i love software development and computers, i&#8217;m really looking forward to not even touching a computer (or any electronic device for that matter) for about 10 days <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .  Who could think of computers when you&#8217;re hanging out a place that looks like this:</p>
<p><img src="http://davybrion.com/blog/wp-content/uploads/2009/06/paradise.jpg" alt="paradise" title="paradise" width="530" height="353" class="aligncenter size-full wp-image-1416" /></p>
<p>I&#8217;ll see you all in about 2 weeks <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F06%2Ftime-for-a-much-needed-break%2F&amp;linkname=Time%20For%20A%20Much%20Needed%20Break" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/ApYRFedgwMd1uVk_vxtRlQ3_278/0/da"><img src="http://feedads.g.doubleclick.net/~a/ApYRFedgwMd1uVk_vxtRlQ3_278/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/ApYRFedgwMd1uVk_vxtRlQ3_278/1/da"><img src="http://feedads.g.doubleclick.net/~a/ApYRFedgwMd1uVk_vxtRlQ3_278/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=qLsS5w1hg4I:_CFVBFHg1KU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=qLsS5w1hg4I:_CFVBFHg1KU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=qLsS5w1hg4I:_CFVBFHg1KU:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/qLsS5w1hg4I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/06/time-for-a-much-needed-break/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/06/time-for-a-much-needed-break/</feedburner:origLink></item>
		<item>
		<title>How Can This Test Fail?</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/Nc-PsJB8rPY/</link>
		<comments>http://davybrion.com/blog/2009/06/how-can-this-test-fail/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 11:46:55 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1412</guid>
		<description><![CDATA[We have a certain class which sometimes makes some tests fail&#8230; the code is old (consider it legacy) but it&#8217;s not that bad&#8230; but we just can&#8217;t figure out why it sometimes causes tests the fail.
Here&#8217;s an example of a test that occasionally fails:


&#160;&#160;&#160; &#160;&#160;&#160; [Test]
&#160;&#160;&#160; &#160;&#160;&#160; public void TestGet_CacheableObjectReturned()
&#160;&#160;&#160; &#160;&#160;&#160; {
&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; TestCacheableObject [...]]]></description>
			<content:encoded><![CDATA[<p>We have a certain class which sometimes makes some tests fail&#8230; the code is old (consider it legacy) but it&#8217;s not that bad&#8230; but we just can&#8217;t figure out why it sometimes causes tests the fail.</p>
<p>Here&#8217;s an example of a test that occasionally fails:</p>
<p><code></p>
<div style="font-family: Consolas; font-size: 9pt; color: black; background: white;">
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span style="color: #2b91af;">Test</span>]</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">void</span> TestGet_CacheableObjectReturned()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: #2b91af;">TestCacheableObject</span> cacheableObject = <span style="color: blue;">new</span> <span style="color: #2b91af;">TestCacheableObject</span>(<span style="color: #a31515;">&quot;test&quot;</span>, 60000);</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CacheProvider.GetInstance().Put(cacheableObject);</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">try</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: #2b91af;">Assert</span>.AreSame(cacheableObject, CacheProvider.GetInstance().Get(<span style="color: #a31515;">&quot;test&quot;</span>));</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">finally</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CacheProvider.GetInstance().Remove(<span style="color: #a31515;">&quot;test&quot;</span>);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
</div>
<p></code>  </p>
<p>If it fails, it&#8217;s on the following line:</p>
<p><code></p>
<div style="font-family: Consolas; font-size: 9pt; color: black; background: white;">
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: #2b91af;">Assert</span>.AreSame(cacheableObject, CacheProvider.GetInstance().Get(<span style="color: #a31515;">&quot;test&quot;</span>));</p>
</div>
<p></code></p>
<p>Sometimes, the Get method of the CacheProvider returns null in this test, even though the cacheable object has just been added to the CacheProvider. </p>
<p>Here&#8217;s the code of the CacheProvider:</p>
<p><code></p>
<div style="font-family: Consolas; font-size: 9pt; color: black; background: white;">
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CacheProvider</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">object</span> monitor = <span style="color: blue;">new</span> <span style="color: blue;">object</span>();</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">CacheProvider</span> _instance;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: #2b91af;">IDictionary</span>&lt;<span style="color: blue;">object</span>, <span style="color: #2b91af;">CacheableObject</span>&gt; _cacheDictionary;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> CacheProvider()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _cacheDictionary = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span>&lt;<span style="color: blue;">object</span>, <span style="color: #2b91af;">CacheableObject</span>&gt;();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">CacheProvider</span> GetInstance()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">lock</span> (monitor)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (_instance == <span style="color: blue;">null</span>)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _instance = <span style="color: blue;">new</span> <span style="color: #2b91af;">CacheProvider</span>();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> _instance;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">void</span> Put(<span style="color: #2b91af;">CacheableObject</span> value)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (ContainsKey(value.Key))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Remove(value.Key);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; value.Provider = <span style="color: blue;">this</span>;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _cacheDictionary.Add(value.Key, value);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; value.StartTicking();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">CacheableObject</span> Get(<span style="color: blue;">object</span> key)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (_cacheDictionary.ContainsKey(key))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> _cacheDictionary[key];</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> <span style="color: blue;">null</span>;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">void</span> Remove(<span style="color: blue;">object</span> key)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _cacheDictionary.Remove(key);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">bool</span> ContainsKey(<span style="color: blue;">object</span> key)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> _cacheDictionary.ContainsKey(key);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p>
</div>
<p></code></p>
<p>This is the code of the CacheableObject class:</p>
<p><code></p>
<div style="font-family: Consolas; font-size: 9pt; color: black; background: white;">
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">abstract</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CacheableObject</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">object</span> _key;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: #2b91af;">CacheProvider</span> _cacheProvider;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: #2b91af;">Timer</span> _timer;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">protected</span> <span style="color: blue;">abstract</span> <span style="color: blue;">double</span> GetTimeToLive();</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> CacheableObject(<span style="color: blue;">object</span> key)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _key = key;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">void</span> StartTicking()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _timer = <span style="color: blue;">new</span> <span style="color: #2b91af;">Timer</span>(GetTimeToLive());</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _timer.Elapsed += Timer_Elapsed;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _timer.Start();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">void</span> Timer_Elapsed(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">ElapsedEventArgs</span> e)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _timer.Stop();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Provider.Remove(<span style="color: blue;">this</span>.Key);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">object</span> Key</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">get</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> _key;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">CacheProvider</span> Provider</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">get</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> _cacheProvider;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">set</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _cacheProvider = <span style="color: blue;">value</span>;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p>
</div>
<p></code></p>
<p>And this is the code of the TestCacheableObject that is used in the failing test:</p>
<p><code></p>
<div style="font-family: Consolas; font-size: 9pt; color: black; background: white;">
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">TestCacheableObject</span> : CacheableObject</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">double</span> _ttl;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> TestCacheableObject(<span style="color: blue;">string</span> key, <span style="color: blue;">double</span> ttl)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; : <span style="color: blue;">base</span>(key)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _ttl = ttl;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">protected</span> <span style="color: blue;">override</span> <span style="color: blue;">double</span> GetTimeToLive()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> _ttl;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
</div>
<p></code></p>
<p>I can&#8217;t for the life of me figure out why the test above fails sometimes. It happens very occassionaly, sometimes it even takes weeks or months before it fails again.  It&#8217;s not just the test above, it&#8217;s basically every test that uses the CacheProvider&#8217;s ContainsKey method (either directly or indirectly) that fails sometimes.</p>
<p>Important note to consider: when these tests fail, they take about 10ms&#8230;</p>
<p>If anyone has a clue what could possibly cause this, i&#8217;d be very willing to hear it <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F06%2Fhow-can-this-test-fail%2F&amp;linkname=How%20Can%20This%20Test%20Fail%3F" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/W-Dg_TUH0l_ND_a4og3w9ffvE4c/0/da"><img src="http://feedads.g.doubleclick.net/~a/W-Dg_TUH0l_ND_a4og3w9ffvE4c/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/W-Dg_TUH0l_ND_a4og3w9ffvE4c/1/da"><img src="http://feedads.g.doubleclick.net/~a/W-Dg_TUH0l_ND_a4og3w9ffvE4c/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=Nc-PsJB8rPY:9IMgQEPUXIQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Nc-PsJB8rPY:9IMgQEPUXIQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Nc-PsJB8rPY:9IMgQEPUXIQ:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/Nc-PsJB8rPY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/06/how-can-this-test-fail/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/06/how-can-this-test-fail/</feedburner:origLink></item>
		<item>
		<title>What Microsoft Should Do For .NET Open Source</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/EawLbOvD5ZA/</link>
		<comments>http://davybrion.com/blog/2009/05/what-microsoft-should-do-for-net-open-source/#comments</comments>
		<pubDate>Mon, 25 May 2009 20:37:06 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Opinions]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1406</guid>
		<description><![CDATA[I recently read Rob Conery&#8217;s &#8220;What Should Microsoft Do For .NET Open Source&#8221; post where he invites people to answer the question he poses in his post.  Obviously, i could not resist posting my thoughts and views on this.
Before i start, i would like to state that i appreciate all of Microsoft&#8217;s recent efforts [...]]]></description>
			<content:encoded><![CDATA[<p>I recently read Rob Conery&#8217;s &#8220;<a href="http://blog.wekeroad.com/blog/what-should-microsoft-do-for-net-open-source/">What Should Microsoft Do For .NET Open Source</a>&#8221; post where he invites people to answer the question he poses in his post.  Obviously, i could not resist posting my thoughts and views on this.</p>
<p>Before i start, i would like to state that i appreciate all of Microsoft&#8217;s recent efforts to move to a more open development model.  I think they&#8217;ve done a pretty good job already but nothing&#8217;s perfect and there&#8217;s always room for improvement.  So let&#8217;s just get to the list of things that i would love to see from Microsoft with regards to dealing with Open Source Software in the .NET world.</p>
<p>First of all, i&#8217;d like to see a completely transparent development model.  I love the fact that ASP.NET MVC is released under an Open Source License, but it would be better if everyone could track the development.  With that i mean access to the internal bug/issue tracker and source code repository.  I want to know what problems are known, and how they are being dealt with.  I want to see the progress in the code.  I want the ability to either run off the trunk, or to merge specific pieces of the trunk into a released version if that enables me to avoid problems that i might run into with an officially released version.  Getting the source code to a released version is (IMO) only a small part of what Open Source development is all about.</p>
<p>I also want them to be open to outside contributions.  I truly hate running into annoying little bugs that won&#8217;t be fixed until the next major version (which sometimes takes a year or 2 to come out) but which could be avoided with a simple patch.  Allow people to contribute patches and you&#8217;d be amazed at the amount of goodwill and support you&#8217;ll create among a vocal group of users.  Obviously, this only works when the development model in general is as open as i mentioned earlier.  Nobody is going to submit patches based on a released version if the actual trunk might already contain fixes or has been modified heavily after the latest release.  And being able to patch a released version for your own use isn&#8217;t always a viable option to most people since you really don&#8217;t want to deal with having to merge the patch when newer versions are released (and all the regression testing that comes with it).</p>
<p>Microsoft should also play nice with other Open Source projects.  Sure, they included JQuery with ASP.NET MVC which is a good move.  But there are a lot of examples where they developed some library or framework for which a generally accepted Open Source alternative was already present.  I still cringe whenever i&#8217;m forced to use MSTest (which to this day is still a pretty crappy testing framework IMHO) while they could&#8217;ve just as easily supported NUnit&#8217;s development.  And if you&#8217;re not happy with NUnit, consider the state of MSTest before you complain about my choice of NUnit over say&#8230; MBUnit or any of the other testing frameworks.  Does anyone remember NDoc? Was Sandcastle really necessary or would it have made more sense to just invest some effort into NDoc instead of starting from scratch?  My biggest issue with this is that Microsoft&#8217;s alternatives can often be used without resistance in certain workplaces, just because it&#8217;s from Microsoft.  It doesn&#8217;t even matter if there are actually better Open Source alternatives available&#8230; In Microsoft we trust, thus Microsoft you&#8217;ll use.  Not always the smartest choice, as i&#8217;m sure many of you will agree with.</p>
<p>Would it really be so bad for Microsoft if they would just assign some developers to help out with projects that already exist?  We now generally have to wait until the third version of any Microsoft product before we really get great quality, while in some cases, a high-quality Open Source alternative was already available from the start.  This often leads to about 3 to 4 years of crappy releases that many people will adopt solely because it&#8217;s from Microsoft and because &#8220;it&#8217;ll improve in the next versions&#8221;.   Even if you don&#8217;t want to assign developers to Open Source projects, it might already be very useful to provide helpful things such as servers, bandwidth, anything that could help out.  Hell, references in official Microsoft documentation on MSDN would already be a huge step up.</p>
<p>There also needs to be some kind of PR cleanup campaign for all of the FUD that Microsoft has spread about Open Source software in general in the past few years.  While it can be argued that that FUD was mainly targeted at GPL software, to many managers in big companies the message came across as &#8220;Do not use Open Source because it&#8217;s a legal minefield&#8221;.   That is a misconception that many .NET developers are still fighting on a daily basis which isn&#8217;t good for anyone.</p>
<p>Then there is the issue of support.  I&#8217;m not going to repeat myself so i&#8217;ll just link to a previous post of mine which covers that topic: <a href="http://davybrion.com/blog/2009/03/support-of-commercial-software-vs-open-source-software/">Support Of Commercial Software vs Open Source Software</a>.  </p>
<p>And as for the host of legal aspects that Microsoft is probably afraid of, i would suggest looking into the reasons why other (large) companies are able to be cooperative citizens within the Open Source world without legal troubles.  Hell, commercial software can be a legal minefield as well so is the Open Source world truly worse?  Maybe they should ask companies like IBM&#8230; surely they have plenty of experience in both cases.</p>
<p>Do i expect or even want Microsoft to open source everything in the .NET world? No.  But i would definitely appreciate it if Microsoft would play nice with other Open Source projects, be a more active participant and be open to outside participation as well.  I&#8217;m sure i won&#8217;t be the only one who thinks so.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fwhat-microsoft-should-do-for-net-open-source%2F&amp;linkname=What%20Microsoft%20Should%20Do%20For%20.NET%20Open%20Source" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/nEjvX_-Fg3NMCTnEiIPf-pTZWOo/0/da"><img src="http://feedads.g.doubleclick.net/~a/nEjvX_-Fg3NMCTnEiIPf-pTZWOo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/nEjvX_-Fg3NMCTnEiIPf-pTZWOo/1/da"><img src="http://feedads.g.doubleclick.net/~a/nEjvX_-Fg3NMCTnEiIPf-pTZWOo/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=EawLbOvD5ZA:aYECmMRsoss:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=EawLbOvD5ZA:aYECmMRsoss:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=EawLbOvD5ZA:aYECmMRsoss:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/EawLbOvD5ZA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/05/what-microsoft-should-do-for-net-open-source/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/05/what-microsoft-should-do-for-net-open-source/</feedburner:origLink></item>
		<item>
		<title>Comment Spam</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/ae1hxl9C-h0/</link>
		<comments>http://davybrion.com/blog/2009/05/comment-spa/#comments</comments>
		<pubDate>Sun, 24 May 2009 20:05:59 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[About The Blog]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1402</guid>
		<description><![CDATA[I used to go over the comments that were marked as spam on a regular basis to check for false positives.  This was pretty doable in the past since i got between 30-50 spam comments on a daily basis and you could usually scroll through them pretty quickly to identify real comments.  Lately [...]]]></description>
			<content:encoded><![CDATA[<p>I used to go over the comments that were marked as spam on a regular basis to check for false positives.  This was pretty doable in the past since i got between 30-50 spam comments on a daily basis and you could usually scroll through them pretty quickly to identify real comments.  Lately though, i&#8217;ve been getting several hundred of spam comments per day and i really don&#8217;t have the time to go through all of that.  Unlike some other bloggers, i refuse to disable commenting in general due to spam so some legit comments might accidentally be flagged as spam and won&#8217;t show up.  So, if you leave a comment and it&#8217;s not showing up immediately, just send me an email (preferably from the same address you filled in for the comment) and i&#8217;ll try to rescue it from the spam filter.  I do delete spammed comments pretty regularly so don&#8217;t wait around if your comment isn&#8217;t displayed immediately <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fcomment-spa%2F&amp;linkname=Comment%20Spam" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/qCc7qMkFODyR713z_pR3kEwJdwQ/0/da"><img src="http://feedads.g.doubleclick.net/~a/qCc7qMkFODyR713z_pR3kEwJdwQ/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/qCc7qMkFODyR713z_pR3kEwJdwQ/1/da"><img src="http://feedads.g.doubleclick.net/~a/qCc7qMkFODyR713z_pR3kEwJdwQ/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=ae1hxl9C-h0:mUNQhVBqaQA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=ae1hxl9C-h0:mUNQhVBqaQA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=ae1hxl9C-h0:mUNQhVBqaQA:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/ae1hxl9C-h0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/05/comment-spa/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/05/comment-spa/</feedburner:origLink></item>
		<item>
		<title>Continuous Integration On A Real, Big Project</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/sY82ELpdMLM/</link>
		<comments>http://davybrion.com/blog/2009/05/continuous-integration-on-a-real-big-project/#comments</comments>
		<pubDate>Sun, 24 May 2009 19:45:54 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Continuous Integration]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1393</guid>
		<description><![CDATA[Some of you may remember a post of mine where i showed the complete lack of attention that was being paid to the Continuous Integration of one of our projects.  This particular project is pretty big.  The development of this project has gone on for years, and will keep going for years to [...]]]></description>
			<content:encoded><![CDATA[<p>Some of you may remember a post of mine where i showed <a href="http://davybrion.com/blog/2009/03/continuous-failure/">the complete lack of attention that was being paid to the Continuous Integration of one of our projects</a>.  This particular project is pretty big.  The development of this project has gone on for years, and will keep going for years to come as it is a strategically important project for us.  The actual system is used internally by our company as well as a growing list of customers.</p>
<p>There are essentially 2 big problems with this project.  One is a mountain of legacy code with so much technical debt (due to <a href="http://davybrion.com/blog/2008/09/beware-the-evils-of-code-generation/">the evils</a> of <a href="http://www.codethinked.com/post/2009/05/05/Code-Generation-Should-be-the-Nuclear-Option.aspx">code generation</a>) it sorta resembles the current economic recession (as in: it&#8217;ll take a <strong>long</strong> time to get everything sorted out).  The other problem is more a matter of organization.  We&#8217;re a pretty small company and while we have great ideas for products, we simply can&#8217;t assign a steady, stable team of developers to work on any of these projects on a continuous basis since we all often need to work on stuff that is simply more lucrative at that particular point in time.  The result is that this particular project typically has an ever rotating group of developers working on it, usually for short periods of time.  Some people work almost full-time on it, but that list is pretty limited. </p>
<p>Not exactly the ideal situation for a large project to apply CI and other agile development practices to, right?  Luckily for us, we&#8217;re quite stubborn and we try to make the best out of every situation.  So back when this project&#8217;s CI success rate was <a href="http://davybrion.com/blog/2009/03/continuous-failure/">only showing a lack of success</a>, we all agreed to follow the <a href="http://davybrion.com/blog/2009/03/continuous-integration-101/">CI rules</a> and at this point, i&#8217;m pretty proud to be able to show you guys the following picture:</p>
<p><img src="http://davybrion.com/blog/wp-content/uploads/2009/05/image001.png" alt="image001" title="image001" width="979" height="864" class="aligncenter size-full wp-image-1394" /></p>
<p>Note: we moved to <a href="http://www.jetbrains.com/teamcity/index.html">Team City</a> in July 2008 so i can&#8217;t show you any earlier data than that.</p>
<p>Anyways, as you can see, after the dismal months of February and March, the success rate of the CI build gradually started improving again.  The average time to fix failing tests also decreased sharply.  We still have failing tests from time to time, but at least now they&#8217;re all dealt with in a timely fashion.  We still have build failures, though those have decreased a lot as well and are always dealt with pretty soon now.  I&#8217;m not sure if this is because of my &#8216;Continuous Bitching&#8217; whenever the build fails, or that everyone bought into the concept of CI again (for my own sake, i&#8217;ll just assume that it&#8217;s the latter instead of the former) but i&#8217;m pretty happy with the results that we&#8217;re getting.</p>
<p>Also, take a look at the number of tests (we&#8217;re at 16000+ now) and the duration of the build.  The build time is about 48 minutes on average now, which is obviously way above the recommended 10 minutes.  I&#8217;d love to see this go down to about 20 minutes (which i&#8217;d find very acceptable considering the size of the project) but that&#8217;s gonna take a long while.  Of those 16000 tests, there are about 13000 tests that cover the legacy code and they <strong>all</strong> use the database.  And since those 13000 tests use a generated data layer, we can&#8217;t just let it run on an in-memory database nor can we mock the database in those tests because all of that generated code, and pretty much everything that was written on top of it, is coupled more tightly than Siamese Twins.  We also lose a couple of minutes of build time due to our <a href="http://davybrion.com/blog/2008/11/genesis-bridging-the-gap-between-requirement-and-code/">Genesis processing</a> but that is simply something that we can&#8217;t go without anymore so we don&#8217;t really mind the extra build time of that part.</p>
<p>So there you have it&#8230; the reason i wanted to post this is because when the topic of CI comes up, you always read about &#8216;instant feedback&#8217; and really quick builds and things like that.  It&#8217;s simply not always like that in the real world.  But with a bit of effort and focus, you can get many of the benefits that are usually attributed to CI, even on huge projects with lots of legacy code.  </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fcontinuous-integration-on-a-real-big-project%2F&amp;linkname=Continuous%20Integration%20On%20A%20Real%2C%20Big%20Project" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/2DVlTN1jRB089Ep16RN_4osYLqM/0/da"><img src="http://feedads.g.doubleclick.net/~a/2DVlTN1jRB089Ep16RN_4osYLqM/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/2DVlTN1jRB089Ep16RN_4osYLqM/1/da"><img src="http://feedads.g.doubleclick.net/~a/2DVlTN1jRB089Ep16RN_4osYLqM/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=sY82ELpdMLM:LWN8PW2dBt0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=sY82ELpdMLM:LWN8PW2dBt0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=sY82ELpdMLM:LWN8PW2dBt0:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/sY82ELpdMLM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/05/continuous-integration-on-a-real-big-project/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/05/continuous-integration-on-a-real-big-project/</feedburner:origLink></item>
		<item>
		<title>Keep An Eye On Those Indexes</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/aRTwe2m9O_g/</link>
		<comments>http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/#comments</comments>
		<pubDate>Thu, 21 May 2009 12:14:57 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1387</guid>
		<description><![CDATA[We have a multi-tenant application, where each tenant has its own database. We recently were informed about a particular performance problem that one tenant (which we&#8217;ll refer to as Tenant A) was experiencing in every screen where data of a certain type needed to be shown.  None of the other tenants experienced this problem [...]]]></description>
			<content:encoded><![CDATA[<p>We have a multi-tenant application, where each tenant has its own database. We recently were informed about a particular performance problem that one tenant (which we&#8217;ll refer to as Tenant A) was experiencing in every screen where data of a certain type needed to be shown.  None of the other tenants experienced this problem though.</p>
<p>We tracked down the query that was causing the bad performance and ran it on the database of Tenant B.  Tenant B actually had a lot more data in the main table that was used in the query and the query executed immediately whereas it took about 25 seconds to complete for Tenant A.   So the query runs fast on another database that actually has more data&#8230; at this point i was convinced that it had to be related to indexes.</p>
<p>Turns out that someone recently ran an import process to import a bunch of data in Tenant A&#8217;s database. I know very little about databases, but one thing i&#8217;ve seen time and time again (with both Oracle and SQL Server) is that you really need to make sure that your indexes are in good shape after any process that performs a lot of inserts (or removals).   A couple of years ago, i had a very intensive nightly import process for a particular project that used an Oracle database.  As time went on, the application&#8217;s queries became painfully (unacceptably even) slow.  I managed to restore the performance of those queries by simply instructing Oracle to recalculate all of the statistics of the indexes of tables that were affected heavily during the nightly import.</p>
<p>With that in mind, we simply rebuilt the indexes for Tenant A&#8217;s database, and the same query that took 25 seconds completed almost instantly from then on.  Now, we did had a weekly job running on that database server to keep the indexes in a healthy shape but that job didn&#8217;t really do a good umm&#8230; job of it, apparently.  </p>
<p>Lessons learned: make sure that you:</p>
<ul>
<li>Have a proper maintenance job set up which keeps your indexes healthy and schedule it to run regularly</li>
<li>Run that job manually if you need to perform a manual import process</li>
<li>Execute that job in an automated fashion whenever an intensive automated import process has completed</li>
</ul>
<p>Oh, and consult with your DBA&#8217;s or at least people who know what they&#8217;re doing when it comes to your particular database on how to keep those indexes healthy.  In this case, we rebuilt them.  In other cases it&#8217;s sufficient to recalculate the statistics&#8230; i&#8217;m not sure which way is the best but you should at least keep an eye on this possible problem <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fkeep-an-eye-on-those-indexes%2F&amp;linkname=Keep%20An%20Eye%20On%20Those%20Indexes" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/RofErIT6cyND-jO8jFbxp1x88LA/0/da"><img src="http://feedads.g.doubleclick.net/~a/RofErIT6cyND-jO8jFbxp1x88LA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/RofErIT6cyND-jO8jFbxp1x88LA/1/da"><img src="http://feedads.g.doubleclick.net/~a/RofErIT6cyND-jO8jFbxp1x88LA/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=aRTwe2m9O_g:SwPmFhYKYxc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=aRTwe2m9O_g:SwPmFhYKYxc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=aRTwe2m9O_g:SwPmFhYKYxc:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/aRTwe2m9O_g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/</feedburner:origLink></item>
		<item>
		<title>Using The Guid.Comb Identifier Strategy</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/UQwlP8tgA0w/</link>
		<comments>http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/#comments</comments>
		<pubDate>Thu, 21 May 2009 12:00:31 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1238</guid>
		<description><![CDATA[As you may have read by now, it&#8217;s a good idea to avoid identity-style identifier strategies with ORM&#8217;s.  One of the better alternatives that i kinda like is the guid.comb strategy.  Using regular guids as a primary key value leads to fragmented indexes (due to the randomness of the guid&#8217;s value) which leads [...]]]></description>
			<content:encoded><![CDATA[<p>As you may have read by now, it&#8217;s a good idea to <a href="http://ayende.com/Blog/archive/2009/03/20/nhibernate-avoid-identity-generator-when-possible.aspx">avoid identity-style identifier strategies</a> with ORM&#8217;s.  One of the better alternatives that i kinda like is the guid.comb strategy.  Using regular guids as a primary key value leads to fragmented indexes (due to the randomness of the guid&#8217;s value) which leads to bad performance.  This is a problem that the guid.comb strategy can solve quite easily for you.</p>
<p>If you want to learn how the guid.comb strategy really works, be sure to check out <a href="http://www.informit.com/articles/article.aspx?p=25862">Jimmy Nilsson&#8217;s article on it</a>. Basically, this strategy generates sequential guids which solves the fragmented index issue.  You can generate these sequential guids in your database, but the downside of that is that your ORM would still need to insert each record seperately and fetch the generated primary key value each time.  NHibernate includes the guid.comb strategy which will generate the sequential guids before actually inserting the records in your database.</p>
<p>This obviously has some great benefits: </p>
<ul>
<li>you don&#8217;t have to hit the database immediately whenever a record needs to be inserted</li>
<li>you don&#8217;t need to retrieve a generated primary key value when a record was inserted</li>
<li>you can batch your insert statements</li>
</ul>
<p>Let&#8217;s see how we can use this with NHibernate.  First of all, you need to map the identifier of your entity like this:</p>
<p><code></p>
<style type="text/css">
.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #a31515; }
.cb3 { color: red; }
</style>
<div class="cf">
<p class="cl"><span class="cb1">&nbsp; &nbsp; &lt;</span><span class="cb2">id</span><span class="cb1"> </span><span class="cb3">name</span><span class="cb1">=</span>&quot;<span class="cb1">Id</span>&quot;<span class="cb1"> </span><span class="cb3">column</span><span class="cb1">=</span>&quot;<span class="cb1">Id</span>&quot;<span class="cb1"> </span><span class="cb3">type</span><span class="cb1">=</span>&quot;<span class="cb1">guid</span>&quot;<span class="cb1"> &gt;</span></p>
<p class="cl"><span class="cb1">&nbsp; &nbsp; &nbsp; &lt;</span><span class="cb2">generator</span><span class="cb1"> </span><span class="cb3">class</span><span class="cb1">=</span>&quot;<span class="cb1">guid.comb</span>&quot;<span class="cb1"> /&gt;</span></p>
<p class="cl"><span class="cb1">&nbsp; &nbsp; &lt;/</span><span class="cb2">id</span><span class="cb1">&gt;</span></p>
</div>
<p></code></p>
<p>And that&#8217;s actually all you have to do.  You don&#8217;t have to assign the primary key values or anything like that.  You don&#8217;t need to worry about them at all.  </p>
<p>Take a look at the following test:</p>
<p><code></p>
<style type="text/css">
.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: #2b91af; }
.cb2 { color: blue; }
.cb3 { color: #a31515; }
.cb4 { color: green; }
</style>
<div class="cf">
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span class="cb1">Test</span>]</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">public</span> <span class="cb2">void</span> InsertsAreOnlyExecutedAtTransactionCommit()</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">var</span> insertCountBefore = sessionFactory.Statistics.EntityInsertCount;</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">using</span> (<span class="cb2">var</span> session = sessionFactory.OpenSession())</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">using</span> (<span class="cb2">var</span> transaction = session.BeginTransaction())</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">for</span> (<span class="cb2">int</span> i = 0; i &lt; 50; i++)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">var</span> category = <span class="cb2">new</span> <span class="cb1">ProductCategory</span>(<span class="cb2">string</span>.Format(<span class="cb3">&quot;category {0}&quot;</span>, i + 1));</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb4">// at this point, the entity doesn't have an ID value yet</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">Assert</span>.AreEqual(<span class="cb1">Guid</span>.Empty, category.Id);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; session.Save(category);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb4">// now the entity has an ID value, but we still haven't hit the database yet</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">Assert</span>.AreNotEqual(<span class="cb1">Guid</span>.Empty, category.Id);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb4">// just verifying that we haven't hit the database yet to insert the new categories</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">Assert</span>.AreEqual(insertCountBefore, sessionFactory.Statistics.EntityInsertCount);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; transaction.Commit();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb4">// only now have the recors been inserted</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">Assert</span>.AreEqual(insertCountBefore + 50, sessionFactory.Statistics.EntityInsertCount);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
</div>
<p></code></p>
<p>Interesting, no? The entities have an ID value after they have been &#8217;saved&#8217; by NHibernate.  But they haven&#8217;t actually been saved to the database yet though.  NHibernate always tries to wait as long as possible to hit the database, and in this case it only needs to hit the database when the transaction is committed.  If you&#8217;ve enabled <a href="http://davybrion.com/blog/2008/10/batching-nhibernates-dm-statements/">batching of DML statements</a>, you could severly reduce the number of times you need to hit the database in this scenario.</p>
<p>And in case you&#8217;re wondering, the generated guids look like this:</p>
<p>81cdb935-d371-4285-9dcb-9bdb0122f25f<br />
a44baf99-58e9-4ad7-9a59-9bdb0122f25f<br />
a88300c2-6d64-4ae3-a55b-9bdb0122f25f<br />
032c7884-da2f-4568-b505-9bdb0122f25f<br />
&#8230;.<br />
70d7713c-b38d-4341-953d-9bdb0122f25f</p>
<p>Notice the last part of the guids&#8230; this is what prevents the index fragmentation.</p>
<p>Obviously, this particular test is not a realistic scenario but i&#8217;m sure you understand how much of an improvement this identifier strategy could provide throughout an entire application.  The only downside (IMO) is that guid&#8217;s aren&#8217;t really human readable so if that is important to you, you should probably look into other identifier strategies.  The HiLo strategy would be particularly interesting in that case, but we&#8217;ll cover that in a later post <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fusing-the-guidcomb-identifier-strategy%2F&amp;linkname=Using%20The%20Guid.Comb%20Identifier%20Strategy" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/jRTnFftRpE_wpw9k6N2tZsnhFmk/0/da"><img src="http://feedads.g.doubleclick.net/~a/jRTnFftRpE_wpw9k6N2tZsnhFmk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/jRTnFftRpE_wpw9k6N2tZsnhFmk/1/da"><img src="http://feedads.g.doubleclick.net/~a/jRTnFftRpE_wpw9k6N2tZsnhFmk/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=UQwlP8tgA0w:T4WUrhqHuEE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=UQwlP8tgA0w:T4WUrhqHuEE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=UQwlP8tgA0w:T4WUrhqHuEE:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/UQwlP8tgA0w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/</feedburner:origLink></item>
		<item>
		<title>Why Are Mutable Value Types Even Possible?</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/BNjGdTTzN50/</link>
		<comments>http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/#comments</comments>
		<pubDate>Sun, 17 May 2009 12:06:07 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1352</guid>
		<description><![CDATA[A coworker of mine was recently trying to figure out why some code wouldn&#8217;t compile.
Consider the following code:


.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }


&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; var point = new System.Windows.Point(5, 7);
&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; point.X = 6;
&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>A coworker of mine was recently trying to figure out why some code wouldn&#8217;t compile.</p>
<p>Consider the following code:</p>
<p><code></p>
<style type="text/css">
.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
</style>
<div class="cf">
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">var</span> point = <span class="cb1">new</span> System.Windows.<span class="cb2">Point</span>(5, 7);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; point.X = 6;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; point.Y = 8;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">Assert</span>.AreEqual(6, point.X);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">Assert</span>.AreEqual(8, point.Y);</p>
</div>
<p></code></p>
<p>This compiles and works.  Now consider the following class:</p>
<p><code></p>
<style type="text/css">
.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
</style>
<div class="cf">
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">class</span> <span class="cb2">SomeClass</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> System.Windows.<span class="cb2">Point</span> SomePoint { <span class="cb1">get</span>; <span class="cb1">set</span>; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
</div>
<p></code></p>
<p>And then this small piece of code:</p>
<p><code></p>
<style type="text/css">
.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
</style>
<div class="cf">
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">var</span> myObject = <span class="cb1">new</span> <span class="cb2">SomeClass</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SomePoint = <span class="cb1">new</span> <span class="cb2">Point</span>(2, 3)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; };</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; myObject.SomePoint.X = 5;</p>
</div>
<p></code></p>
<p>You&#8217;d typically expect that this code would compile, right? Well it doesn&#8217;t.  It fails with the following compiler error:</p>
<p>error CS1612: Cannot modify the return value of &#8216;SomeApp.SomeClass.SomePoint&#8217; because it is not a variable</p>
<p>Not exactly what you would expect, right? Well, the compiler error in this case is actually a good thing, though the message isn&#8217;t as clear as it should be.  See, System.Windows.Point is actually a value type instead of a reference type, and as you should know, value types behave very differently from reference types when passed around.  You basically get a copy every time instead of the actual instance.</p>
<p>Let me just borrow the explanation of the &#8220;DO NOT define mutable value types&#8221; guideline, from Microsoft&#8217;s <a href="http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321545613/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1241181546&#038;sr=8-1">Framework Design Guidelines</a>:</p>
<blockquote><p>
Mutable value types have several problems.  For example, when a property getter returns a value type, the caller receives a copy. Because the copy is created implicitly, developers might not be aware that they are mutating the copy, and not the original value.
</p></blockquote>
<p>Now the compiler error makes sense, right? Well, the message still sucks, but it makes sense that the compiler would protect you from making this mistake.</p>
<p>It won&#8217;t protect you from the following mistake though:</p>
<p><code></p>
<style type="text/css">
.cf { font-family: Consolas; font-size: 9pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
</style>
<div class="cf">
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">var</span> myObject = <span class="cb1">new</span> <span class="cb2">SomeClass</span></p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SomePoint = <span class="cb1">new</span> <span class="cb2">Point</span>(2, 3)</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; };</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">var</span> point = myObject.SomePoint;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; point.X = 5;</p>
</div>
<p></code></p>
<p>This code will compile, though if you expect that myObject.SomePoint.X will return 5, you&#8217;re in for a treat.  Hopefully nobody writes code like this, but imagine having to debug something like this in some legacy code that was never properly tested.</p>
<p>But really, why are mutable value types even possible? In what situation does a mutable value type make sense? I&#8217;d really like to know, so please point out those situations in the comments if you know of one.  The only reason i can think of is performance but the number of situations where a mutable value type is going to give you a significant performance boost is probably so small that it would&#8217;ve made more sense to enable mutability for value types with a language keyword or something like that.  Unless there is another benefit that i&#8217;m not aware of yet?</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fwhy-are-mutable-value-types-even-possible%2F&amp;linkname=Why%20Are%20Mutable%20Value%20Types%20Even%20Possible%3F" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/4QRFsEB2lPhCfVVuF_Jqe1rIZo0/0/da"><img src="http://feedads.g.doubleclick.net/~a/4QRFsEB2lPhCfVVuF_Jqe1rIZo0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/4QRFsEB2lPhCfVVuF_Jqe1rIZo0/1/da"><img src="http://feedads.g.doubleclick.net/~a/4QRFsEB2lPhCfVVuF_Jqe1rIZo0/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=BNjGdTTzN50:K3QWtpj1MHI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=BNjGdTTzN50:K3QWtpj1MHI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=BNjGdTTzN50:K3QWtpj1MHI:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/BNjGdTTzN50" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/</feedburner:origLink></item>
		<item>
		<title>Who’s In Charge Of The Time?</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/t1ys9HwounY/</link>
		<comments>http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/#comments</comments>
		<pubDate>Wed, 06 May 2009 16:53:07 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1356</guid>
		<description><![CDATA[I recently noticed that 2 tests were suddenly failing for no apparent reason.  This was in a large codebase where we have a mix of two development approaches.  The project is simply too big to convert everything at once to the latest development approach so we&#8217;re using Ayende&#8217;s Obsolete In Isolation approach on [...]]]></description>
			<content:encoded><![CDATA[<p>I recently noticed that 2 tests were suddenly failing for no apparent reason.  This was in a large codebase where we have a mix of two development approaches.  The project is simply too big to convert everything at once to the latest development approach so we&#8217;re using Ayende&#8217;s <a href="http://ayende.com/Blog/archive/2008/07/14/Obsolete-in-Isolation.aspx">Obsolete In Isolation</a> approach on this.  The 2 failing tests were in the old parts of the code, so i cringed and then set out to investigate.  </p>
<p>The tests of the old part of the code aren&#8217;t always easy to comprehend and they use the database all over the place.  I figured i&#8217;d quickly run them on the database that we use when we run those tests on our local machines, and after that, run them on the database that the buildserver uses (which is rebuilt entirely with each build) to examine the differences between both test runs.  They both passed in both cases.  They were still failing on the buildserver though.</p>
<p>Upon first inspection of the code of those tests, it didn&#8217;t seem like there was any blatantly obvious reason why those tests were failing on one machine, and not on the others.  They were inserting some records with some manipulated DateTime values, and then calling some code which would execute a query which should have retrieved these values.  The records inserted by the test were not retrieved for some reason, which caused the tests to fail.  </p>
<p>DateTime values and tests can be tricky sometimes so i started looking in that direction.  The queries that where executed in those tests would use the current date/time together with a margin of a couple of minutes to retrieve records where a certain date/time column&#8217;s value would fall in the range of the current date/time with the given margin.  The records that were inserted in the tests would use the current date/time, minus 2 minutes, or plus 2 minutes.  Hmm&#8230; this could possibly be flaky depending on how the query determines the current date/time.  If the query receives the current date/time from the calling code, then this wouldn&#8217;t cause problems but if it uses the current date/time of the database, then this is not only a flaky test, but a real bug in the code.</p>
<p>I then checked the system clock of the buildserver, and as i suspected, it was about 4 minutes ahead of the system clock of the database server.  Normally, all of our servers&#8217; system clocks are synchronized, but for some reason, the buildserver hadn&#8217;t had its system clock synchronized since the day before.  The code was inserting records in the database with modified date/time values, based on the system clock of the system the code was running on, and was then querying the database using the database&#8217;s system clock.  Since the time difference was big enough, the query would not return the expected rows and this made the tests fail on the buildserver.</p>
<p>Obviously, this never would&#8217;ve happened if the query would&#8217;ve used a parameter supplied by the caller which would&#8217;ve represented the current date.  And that is the real bug that these flaky tests (which up until this particular incident never failed) highlighted.  A situation like this could&#8217;ve occurred in production if the application server&#8217;s clock and the database server&#8217;s clock would&#8217;ve gotten out of synch.  Can you imagine the pain you&#8217;d go through when investigating a bug report like this? :p</p>
<p>Date/Time values are often tricky, especially when there is more than one source which could determine the current Date/Time.  So do yourself, and anyone who will maintain your code down the line, a favor by making sure that only ONE source is in charge of Date/Time values in your system.  Using the database for all date/time values is definitely not always possible, so it&#8217;s best to have your application server be in charge of all date/time values.  If you need the current date/time in a query, simply supply it as a parameter to the query and you&#8217;ll avoid problems like this.</p>
<p>Though this advice does leave me wondering what the best approach to deal with this is when you have multiple application servers which could assign date/time values.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fwhos-in-charge-of-the-time%2F&amp;linkname=Who%26%238217%3Bs%20In%20Charge%20Of%20The%20Time%3F" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/MU7zILRFhrHuv9anUNWSF-NeuvU/0/da"><img src="http://feedads.g.doubleclick.net/~a/MU7zILRFhrHuv9anUNWSF-NeuvU/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/MU7zILRFhrHuv9anUNWSF-NeuvU/1/da"><img src="http://feedads.g.doubleclick.net/~a/MU7zILRFhrHuv9anUNWSF-NeuvU/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=t1ys9HwounY:LCFejf0czx4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=t1ys9HwounY:LCFejf0czx4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=t1ys9HwounY:LCFejf0czx4:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/t1ys9HwounY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/</feedburner:origLink></item>
		<item>
		<title>On Getting Rid Of Common Libraries… What About Don’t Repeat Yourself?</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/Xft8J4KjFeI/</link>
		<comments>http://davybrion.com/blog/2009/05/on-getting-rid-of-common-libraries-what-about-dont-repeat-yourself/#comments</comments>
		<pubDate>Sat, 02 May 2009 17:26:49 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Opinions]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1372</guid>
		<description><![CDATA[Just wanted to post a small reaction to Ayende&#8217;s dismissal of Util &#038; Common Libraries.  In his post, Ayende goes over everything that Rhino.Commons (his own library) offers and why he&#8217;s not using it anymore.  If you go over the list of everything in the library, i can definitely see why.  As [...]]]></description>
			<content:encoded><![CDATA[<p>Just wanted to post a small reaction to Ayende&#8217;s <a href="http://ayende.com/Blog/archive/2009/04/29/let-us-burn-all-those-pesky-util-amp-common-libraries.aspx">dismissal of Util &#038; Common Libraries</a>.  In his post, Ayende goes over everything that Rhino.Commons (his own library) offers and why he&#8217;s not using it anymore.  If you go over the list of everything in the library, i can definitely see why.  As Ayende says, it&#8217;s the garbage bin for anything that he came up with in the past couple of years, regardless of how many projects would actually reuse each specific part.</p>
<p>At work we have also have something like this, though in some ways it&#8217;s smaller in scale, and in some ways it offers a bit more than Rhino Commons.  A lot of it is based, or are further developed versions of, the infrastructural bits that i&#8217;ve posted on this blog in the last year.  We also have some other interesting things in there that my coworkers wrote.  We took the opposite direction however.  </p>
<p>We started off with putting these classes in each project where we could use them.  But since a lot of that stuff was still being modified or extended on a semi regular basis, we were constantly making the same changes or additions in multiple places, which violates the Don&#8217;t Repeat Yourself principle.  Essentially, it was duplicate code, just spread in multiple projects.  Obviously, this brought along all of the same problems that duplicate code usually brings with it.  </p>
<p>So we set out to figure out to best way to deal with this, and i even <a href="http://davybrion.com/blog/2008/12/how-do-you-deal-with-common-infrastructure-code-for-multiple-projects/">asked you guys</a> about it.  We eventually ended up moving these bits to some sort of in-house library/framework that all (or most) of our applications now use.  While i was the one who was hesitant at first to go with a reusable library/framework (due to some bad experiences with it in the past), i&#8217;m now very glad we actually did do it. </p>
<p>We did go for multiple assemblies (ie: web, silverlight, service layer, &#8230;) instead of putting everything in one big assembly though we did try to follow my &#8216;<a href="http://davybrion.com/blog/2008/07/many-projects-dont-lead-to-a-good-solution/">one assembly per physical deployment</a>&#8216; rule.</p>
<p>Bugs get fixed in one place and one place only.  The only repetitiveness we have to endure when fixing a bug in the library is making sure we can merge the fix to previous versions and updating the referenced binaries in each project that uses it.  That&#8217;s it.  New stuff only gets added when it&#8217;s been proven to be useful in more than one project.  We don&#8217;t just add new things like that, unless it really makes sense to do so.  </p>
<p>I think most of the problems that Ayende now sees with Rhino Commons can be avoided by splitting things up a bit more, and by being more restrictive as to what actually makes it into the library.  Versioning suddenly becomes pretty important as well.  These are all things that i always felt where somewhat missing with Rhino Commons.  That&#8217;s not to criticize the project because i do think there&#8217;s a lot of valuable stuff in there, but in it&#8217;s current form it&#8217;s just not very well suited to be reused by other projects.</p>
<p>Having said all that, i&#8217;m not saying that reusable libraries/frameworks are the best thing since sliced bread either.  They require a lot of discipline and it&#8217;s easy to get tripped up simply by adding something or making a minor change where you didn&#8217;t really think all of the consequences through.  But the downsides of dealing with these libraries are usually smaller than the downsides of having the same code spread out over multiple projects.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fon-getting-rid-of-common-libraries-what-about-dont-repeat-yourself%2F&amp;linkname=On%20Getting%20Rid%20Of%20Common%20Libraries%26%238230%3B%20What%20About%20Don%26%238217%3Bt%20Repeat%20Yourself%3F" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/IC0CZjtEDmyZVnxE5ITtNBxuqzs/0/da"><img src="http://feedads.g.doubleclick.net/~a/IC0CZjtEDmyZVnxE5ITtNBxuqzs/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/IC0CZjtEDmyZVnxE5ITtNBxuqzs/1/da"><img src="http://feedads.g.doubleclick.net/~a/IC0CZjtEDmyZVnxE5ITtNBxuqzs/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=Xft8J4KjFeI:nzejUrwQgro:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Xft8J4KjFeI:nzejUrwQgro:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Xft8J4KjFeI:nzejUrwQgro:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/Xft8J4KjFeI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/05/on-getting-rid-of-common-libraries-what-about-dont-repeat-yourself/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/05/on-getting-rid-of-common-libraries-what-about-dont-repeat-yourself/</feedburner:origLink></item>
		<item>
		<title>Using SQL Functions in Criteria Restrictions</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/sT6qVAQFrQo/</link>
		<comments>http://davybrion.com/blog/2009/04/using-sql-functions-in-criteria-restrictions/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 11:31:53 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1348</guid>
		<description><![CDATA[A coworker needed to use a SQL function in the where clause of a query that he was creating with NHibernate&#8217;s ICriteria API.  Most examples of this on the web use HQL instead of the ICriteria API and since we primarily use the ICriteria API we looked into how to do this.
Turns out it [...]]]></description>
			<content:encoded><![CDATA[<p>A coworker needed to use a SQL function in the where clause of a query that he was creating with NHibernate&#8217;s ICriteria API.  Most examples of this on the web use HQL instead of the ICriteria API and since we primarily use the ICriteria API we looked into how to do this.</p>
<p>Turns out it is pretty simple to do, though the syntax isn&#8217;t really straightforward.  Suppose you want to query all of your employees who are born in a specific year.  You could mess around with some DateTime parameters, but most databases have SQL functions to get the year from a date.  Using the ICriteria API, this would look like this:</p>
<p><code></p>
<div style="font-family: Consolas; font-size: 9pt; color: black; background: white;">
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">var</span> employeesBornIn81 = session.CreateCriteria&lt;<span style="color: #2b91af;">Employee</span>&gt;()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .Add(<span style="color: #2b91af;">Restrictions</span>.Eq(<span style="color: #2b91af;">Projections</span>.SqlFunction(<span style="color: #a31515;">&quot;year&quot;</span>, <span style="color: #2b91af;">NHibernateUtil</span>.DateTime, <span style="color: #2b91af;">Projections</span>.Property(<span style="color: #a31515;">&quot;BirthDate&quot;</span>)), 1981))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .List&lt;<span style="color: #2b91af;">Employee</span>&gt;();</p>
</div>
<p></code></p>
<p>which adds the following where clause to the SQL statement (on SQL Server 2005):</p>
<p>WHERE datepart(year, this_.BirthDate) = @p0;</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Fusing-sql-functions-in-criteria-restrictions%2F&amp;linkname=Using%20SQL%20Functions%20in%20Criteria%20Restrictions" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/IrOUKJbz9enJ0ff11Zm8Vj5uKyI/0/da"><img src="http://feedads.g.doubleclick.net/~a/IrOUKJbz9enJ0ff11Zm8Vj5uKyI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/IrOUKJbz9enJ0ff11Zm8Vj5uKyI/1/da"><img src="http://feedads.g.doubleclick.net/~a/IrOUKJbz9enJ0ff11Zm8Vj5uKyI/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=sT6qVAQFrQo:n675IHgPhFE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=sT6qVAQFrQo:n675IHgPhFE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=sT6qVAQFrQo:n675IHgPhFE:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/sT6qVAQFrQo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/04/using-sql-functions-in-criteria-restrictions/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/04/using-sql-functions-in-criteria-restrictions/</feedburner:origLink></item>
		<item>
		<title>The Good, The Bad And The Ugly In The .NET World</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/3wNM6cH9zxc/</link>
		<comments>http://davybrion.com/blog/2009/04/the-good-the-bad-and-the-ugly-in-the-net-world/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 21:21:37 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Opinions]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1340</guid>
		<description><![CDATA[I&#8217;ve gotten quite a bit of feedback on my previous post, and there are a couple of things i&#8217;d like to address.  It seems that some people kinda took offense to my statements about the rarity of .NET developers with knowledge of certain practices/principles.  First of all, i would like to state that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve gotten quite a bit of feedback on my <a href="http://davybrion.com/blog/2009/04/at-this-point-id-prefer-java-developers-over-net-developers/">previous post</a>, and there are a couple of things i&#8217;d like to address.  It seems that some people kinda took offense to my statements about the rarity of .NET developers with knowledge of certain practices/principles.  First of all, i would like to state that i have been working in the .NET world for about 4 years now and have worked with quite a few .NET developers during those years.  Most of you already know this and i feel stupid for even mentioning it, but apparently there were people who read the previous post thinking i didn&#8217;t know anything about the .NET world and that i had based my statements on just the one .NET developer that i mentioned in the post.  </p>
<p>Anyways, back to the topic at hand&#8230; the quality of developers in the .NET world.  As some people mentioned in the comments of the previous post, Microsoft itself thinks of developers in 3 categories: Mort, Einstein and Elvis.  I couldn&#8217;t really find an &#8216;official&#8217; Microsoft link about these personas but they are <a href="http://www.nikhilk.net/Personas.aspx">pretty</a> <a href="http://www.codinghorror.com/blog/archives/001004.html">well</a> <a href="http://www.hanselman.com/blog/BeyondElvisEinsteinAndMortNewProgrammingStereotypesForWeb20.aspx">known</a> by now.  Here&#8217;s a quick summary:</p>
<blockquote><p>
Mort, the opportunistic developer, likes to create quick-working solutions for immediate problems and focuses on productivity and learn as needed. Elvis, the pragmatic programmer, likes to create long-lasting solutions addressing the problem domain, and learn while working on the solution. Einstein, the paranoid programmer, likes to create the most efficient solution to a given problem, and typically learn in advance before working on the solution.
</p></blockquote>
<p>I believe that Mort is the single most influential individual in the .NET world.  Everything revolves around Mort, and this is where a lot of the strengths and weaknesses of the .NET platform in general come from.</p>
<p>People who are new to .NET can usually be productive in a pretty short timeframe.  The tools are often relatively easy to use and there is plenty of documentation and Getting Started material available.  No matter how you turn it, that is a strength of the platform.  However, what is generally lacking here is some kind of follow-through on the fundamentals of healthy, maintainable software development.  We&#8217;ve all seen the countless simplified, hello-world examples that are often demonstrated at Microsoft events.  Some <a href="http://codebetter.com/blogs/gregyoung/archive/2009/04/28/java-vs-net-developers.aspx">people consider me arrogant</a> when i say this, but i truly believe that this kind of Drag-N-Drop Development is generally unhealthy.  Does it have its place in the right context? Sure, as much as just about anything else has within its context.  Take it outside of its context and things can get messy pretty fast. </p>
<p>Getting Mort hooked on this kind of development, without following through on Mort&#8217;s education is like teaching construction workers how to quickly put up a wall without educating them about making sure that wall is gonna hold up over the years through all of the forces that will act upon it.  But hey, the wall is there, right? Time to move on to the next wall!  Or better yet, let&#8217;s have Mort do some electrical work while he&#8217;s at it.  After all, we already know he&#8217;s adept at construction and he finishes his work quickly.  Whenever he has a few minutes time, we&#8217;re going to have him work on the plumbing as well.  He&#8217;s got a great set of tools at his disposal, so he should be able to do all of this pretty quickly without investing too much time in his educational process.  </p>
<p>There are tons of Morts in the .NET world.  And Microsoft is constantly building and releasing more and more libraries and tools to make sure that Mort can quickly complete any task that is assigned to him, no matter how fit or unfit he is to complete that task in a sufficient manner.  I think we all know that there is a lot of horrible .NET code that has been written over the years and i truly believe that a lot of that could have been avoided if more effort had been put into properly educating Mort.  </p>
<p>Steven Smith left the following gem in <a href="http://davybrion.com/blog/2009/04/at-this-point-id-prefer-java-developers-over-net-developers/#comment-13705">his comment on my previous post</a>:</p>
<blockquote><p>In the Microsoft space rather than respond to the increasing demands for greater productivity by always seeking more productive and powerful development practices, that is how can we use our tools more effectively, the general mindset seems to be that Microsoft is bringing out a new version of .NET or some new visual tooling, what we perceive to be a more powerful tool and will solve our problem. But a powerful tool misused can cause a great deal of damage. Developer’s continuing professional development seems to consist of learning new Microsoft or third party APIs or attending Tech Ed rather than learning development principles and practices that are language and provider independent.</p></blockquote>
<p>I think i can safely say that this will sound very familiar to a lot of you who are reading this.</p>
<p>So, is all hope lost? Certainly not.  In the past 2 years, we&#8217;ve seen some tremendous improvements in the .NET community, mostly brought on by the ALT.NET movement which focused more on writing clean, maintainable code using proven design practices and software development principles in general.  Regardless of what you (or me) personally think of the ALT.NET movement in its current form (or lack thereof), there is no denying the impact that it has had already.  Microsoft appears to be focusing more and more on the topics that are typically associated with ALT.NET.  All of a sudden, Microsoft has libraries for Inversion Of Control, for MVC web development, Object Relational Mapping, and more.  These tools might not appeal to everyone who&#8217;s already used more mature/powerful alternatives, they are still a very good sign.  It not only shows that Microsoft is willing to invest more effort into this, but it also increases the exposure of these principles and practices to Mort.  It&#8217;s a slow process for sure, but the wheels do appear to have been put in motion.</p>
<p>If we can combine this with a more concentrated educational effort, we might be able to get to where Steven Smith and myself would like to get:</p>
<blockquote><p>
I would love to work with kindred spirits, people who consider their effectiveness as a developer is largely based on the power of the practices they employ and are always seeking more powerful practices that are being developed in the wider development community and apply them in their .NET teams.
</p></blockquote>
<p>Perhaps someday the majority of us, instead of a very small minority, will.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Fthe-good-the-bad-and-the-ugly-in-the-net-world%2F&amp;linkname=The%20Good%2C%20The%20Bad%20And%20The%20Ugly%20In%20The%20.NET%20World" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/SYl2W5_qu2wc_V5Yu2lQz99ADTA/0/da"><img src="http://feedads.g.doubleclick.net/~a/SYl2W5_qu2wc_V5Yu2lQz99ADTA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/SYl2W5_qu2wc_V5Yu2lQz99ADTA/1/da"><img src="http://feedads.g.doubleclick.net/~a/SYl2W5_qu2wc_V5Yu2lQz99ADTA/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=3wNM6cH9zxc:V6eseCstZgE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=3wNM6cH9zxc:V6eseCstZgE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=3wNM6cH9zxc:V6eseCstZgE:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/3wNM6cH9zxc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/04/the-good-the-bad-and-the-ugly-in-the-net-world/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/04/the-good-the-bad-and-the-ugly-in-the-net-world/</feedburner:origLink></item>
		<item>
		<title>At This Point, I’d Prefer Java Developers Over .NET Developers</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/ZMv-d1G-BXI/</link>
		<comments>http://davybrion.com/blog/2009/04/at-this-point-id-prefer-java-developers-over-net-developers/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 20:37:18 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Opinions]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1336</guid>
		<description><![CDATA[I had to do 5 technical screenings today.  4 of these guys where Java developers, one of them a .NET developer.  A couple of weeks ago, i also had to screen a Java developer.  I&#8217;m gonna be blunt about this: at this point, i would much rather hire a Java developer than [...]]]></description>
			<content:encoded><![CDATA[<p>I had to do 5 technical screenings today.  4 of these guys where Java developers, one of them a .NET developer.  A couple of weeks ago, i also had to screen a Java developer.  I&#8217;m gonna be blunt about this: at this point, i would much rather hire a Java developer than a .NET developer.</p>
<p>Let me just summarize these screenings to illustrate my point.  Out of the 5 java developers i had to screen recently, 4 of them were very familiar with topics such as Inversion Of Control, Dependency Injection, Object Relational Mapping, and Aspect Oriented Programming.  One of them was a &#8216;junior&#8217; developer with about 2 years of experience, and we actually talked about the differences between compile time AOP weaving vs runtime weaving, even going into the differences between dynamic proxies and more traditional proxies to achieve AOP and how that would work and how it can be tied into your IOC container.  This wasn&#8217;t just me talking about this stuff&#8230; i was leading into certain things and he was filling in the blanks.  During a technical screening.  With a guy who only has 2 years of experience on his resume.  </p>
<p>The other 3 java developers i screened where pretty impressive as well.  These guys truly realized the benefits of using an Inversion Of Control container, of using Dependency Injection and felt it was only natural to use an ORM when working on typical business applications.  And you know what the really cool part about all this was?  All 4 of those java developers that impressed me wanted to learn more about TDD, and writing automated tests in general.  They hadn&#8217;t really experienced Continuous Integration yet.  They wanted to improve their TDD skills.  They genuinely seemed to care about the fact that their TDD skills weren&#8217;t as well-rounded yet as they could be.  In case you haven&#8217;t noticed, these people truly believe in DI and IOC without even getting into the testability aspect.  </p>
<p>In the .NET world however, most people who get into DI and IOC usually do it for testing purposes, only to move on to the other benefits of it later on.   And that is if you&#8217;re lucky enough to find a .NET developer who even cares about these things.  Generally speaking, you should consider yourself lucky if you get to screen a .NET developer who&#8217;s interested in these &#8216;alternative&#8217; practices (in the .NET universe anyway), let alone one who actually has experience with them.  The odds of finding .NET developers like this in interviews are so incredibly low it&#8217;s not even funny anymore.  It&#8217;s downright pathetic actually.   And then you get 3 of these guys in one day, though they are java developers.  4 of them if you count the one from a few weeks ago.  These numbers don&#8217;t truly mean anything, but still&#8230; i think it&#8217;s worth thinking about.  </p>
<p>Now, i&#8217;m not going to say that Java developers are by definition better than .NET developers.  But i really do think that, generally speaking, they know a lot more about proper design principles and coding practices than your average .NET developer.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Fat-this-point-id-prefer-java-developers-over-net-developers%2F&amp;linkname=At%20This%20Point%2C%20I%26%238217%3Bd%20Prefer%20Java%20Developers%20Over%20.NET%20Developers" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/YaYSySmE_ANgxykP9vG2mwQHxfU/0/da"><img src="http://feedads.g.doubleclick.net/~a/YaYSySmE_ANgxykP9vG2mwQHxfU/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/YaYSySmE_ANgxykP9vG2mwQHxfU/1/da"><img src="http://feedads.g.doubleclick.net/~a/YaYSySmE_ANgxykP9vG2mwQHxfU/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=ZMv-d1G-BXI:SAP8I1meRrc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=ZMv-d1G-BXI:SAP8I1meRrc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=ZMv-d1G-BXI:SAP8I1meRrc:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/ZMv-d1G-BXI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/04/at-this-point-id-prefer-java-developers-over-net-developers/feed/</wfw:commentRss>
		<slash:comments>82</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/04/at-this-point-id-prefer-java-developers-over-net-developers/</feedburner:origLink></item>
		<item>
		<title>Help Us Name This Method</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/DhrfgZ0AI0c/</link>
		<comments>http://davybrion.com/blog/2009/04/help-us-name-this-method/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 13:48:35 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1334</guid>
		<description><![CDATA[This worked pretty good last time so i&#8217;m gonna try it again.  We have a Repository base class (yes we still use it, and no, i&#8217;m not going to get into the discussion that&#8217;s going on about in on other blogs) which uses NHibernate underneath.  We have the typical Get method which retrieves [...]]]></description>
			<content:encoded><![CDATA[<p>This worked pretty good <a href="http://davybrion.com/blog/2009/03/help-us-name-this-property/">last time</a> so i&#8217;m gonna try it again.  We have a Repository base class (yes we still use it, and no, i&#8217;m not going to get into the discussion that&#8217;s going on about in on other blogs) which uses NHibernate underneath.  We have the typical Get method which retrieves an object based on an ID.  This method uses NHibernate&#8217;s ISession&#8217;s Get method, which either returns the entity if it&#8217;s present in the database, or it returns null.</p>
<p>Some people want to put an equivalent to NHibernate&#8217;s ISession&#8217;s Load method into the base repository class, but we just can&#8217;t come up with a good name for it.  In case you don&#8217;t know, ISession.Load either returns the actual entity if it&#8217;s already in the session cache, or it returns a proxy for the entity but it does not immediately hit the database.  The functionality of the Load method is thus very different from the Get method.  Now, i think this is a case of extremely bad naming within NHibernate, and i don&#8217;t want to have the same naming issue in our Repository implementation.  </p>
<p>So basically, the question is: how would you name the equivalent of the Load method? Remember: this method returns a proxy to an entity if it&#8217;s not yet in the session cache, whereas the Get method actually retrieves the entity from the database immediately or returns null if the entity for the given ID does not exist.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Fhelp-us-name-this-method%2F&amp;linkname=Help%20Us%20Name%20This%20Method" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/0HXb6DG_1qwr5ZqvTnQZzM2XBUc/0/da"><img src="http://feedads.g.doubleclick.net/~a/0HXb6DG_1qwr5ZqvTnQZzM2XBUc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/0HXb6DG_1qwr5ZqvTnQZzM2XBUc/1/da"><img src="http://feedads.g.doubleclick.net/~a/0HXb6DG_1qwr5ZqvTnQZzM2XBUc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=DhrfgZ0AI0c:spVuVl5eq-A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=DhrfgZ0AI0c:spVuVl5eq-A:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=DhrfgZ0AI0c:spVuVl5eq-A:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/DhrfgZ0AI0c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/04/help-us-name-this-method/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/04/help-us-name-this-method/</feedburner:origLink></item>
		<item>
		<title>Small Milestone</title>
		<link>http://feedproxy.google.com/~r/davybrion/~3/WAw-k8Rgq7s/</link>
		<comments>http://davybrion.com/blog/2009/04/small-milestone/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 11:20:57 +0000</pubDate>
		<dc:creator>Davy Brion</dc:creator>
				<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://davybrion.com/blog/?p=1329</guid>
		<description><![CDATA[
Finally  
]]></description>
			<content:encoded><![CDATA[<p><img src="http://davybrion.com/blog/wp-content/uploads/2009/04/subscriber_count.png" alt="subscriber_count" title="subscriber_count" width="99" height="31" class="alignnone size-full wp-image-1330" /></p>
<p>Finally <img src='http://davybrion.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Fsmall-milestone%2F&amp;linkname=Small%20Milestone" target="_blank"><img src="http://davybrion.com/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>
<p><a href="http://feedads.g.doubleclick.net/~a/9ixhwBXbOW3ZsImJKaMeHxmiNLk/0/da"><img src="http://feedads.g.doubleclick.net/~a/9ixhwBXbOW3ZsImJKaMeHxmiNLk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/9ixhwBXbOW3ZsImJKaMeHxmiNLk/1/da"><img src="http://feedads.g.doubleclick.net/~a/9ixhwBXbOW3ZsImJKaMeHxmiNLk/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=WAw-k8Rgq7s:U6i5ohZqHYE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=WAw-k8Rgq7s:U6i5ohZqHYE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=WAw-k8Rgq7s:U6i5ohZqHYE:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/WAw-k8Rgq7s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://davybrion.com/blog/2009/04/small-milestone/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://davybrion.com/blog/2009/04/small-milestone/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 1.166 seconds. --><!-- Cached page generated by WP-Super-Cache on 2009-07-06 01:23:56 -->
