<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Wibber&#039;s Blog</title>
	<atom:link href="http://kwiebke.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://kwiebke.wordpress.com</link>
	<description></description>
	<lastBuildDate>Sun, 22 Jan 2012 16:37:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='kwiebke.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Wibber&#039;s Blog</title>
		<link>http://kwiebke.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://kwiebke.wordpress.com/osd.xml" title="Wibber&#039;s Blog" />
	<atom:link rel='hub' href='http://kwiebke.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Getting our SCRUM on #4</title>
		<link>http://kwiebke.wordpress.com/2012/01/22/getting-our-scrum-on-4/</link>
		<comments>http://kwiebke.wordpress.com/2012/01/22/getting-our-scrum-on-4/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 16:20:02 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[SCRUM]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/?p=89</guid>
		<description><![CDATA[The Year In Review We’re finishing our first year with SCRUM and I thought I’d recap the highs and lows that I’ve observed.  For me, this is the most enjoyable thing I’ve done in my 20+ year career in IT. Highs   The teams have delivered more than anyone thought was possible.  Compared to the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=89&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2><span style="color:#ff8000;font-size:large;">The Year In Review</span></h2>
<p>We’re finishing our first year with SCRUM and I thought I’d recap the highs and lows that I’ve observed.  For me, this is the most enjoyable thing I’ve done in my 20+ year career in IT.</p>
<h2><span style="color:#0080ff;">Highs</span></h2>
<div id="highs">
<ul>
<li>  The teams have delivered more than anyone thought was possible.  Compared to the old methods where there were endless hours in meetings arguing over this word or that word, the teams got down to business and cranked code.</li>
<li>  Quality is very good for the teams that implemented automation.  Simple things like automating builds, writing automated unit testing and implementing automated QA scripts has proven a huge win.  Utilizing automation emboldens the teams to make changes that they normally would be afraid to implement.</li>
<li>  Our business partners are engaged and enjoy being part of the process.  They love being able to adjust features every few weeks and not being told “NO” constantly.  At times, they haven’t liked having to make tough decisions about one feature or another, but in the end, they’d never want to go back to waterfail.</li>
<li>  If you follow the process, there really is transparency concerning progress and issues.  For the teams that have done burn-up charts (trend towards release scope), they have been spot on.  Velocity provides a good measure of just how much a team can accomplish sprint by sprint and the burn downs let you know whether you’re on track or if you’ve bit off more than you can chew.</li>
<li>  Presenting the working product at the end of every sprint has given team members visibility to executives that they’d never experienced before.  The executives have really enjoyed getting to meet the unsung heroes who build their systems.  There’s a real sense of pride on the teams when “C” level execs take time out of their schedules to talk to them.</li>
</ul>
</div>
<h2><span style="color:#c0504d;">Lows</span></h2>
<div id="lows">
<ul>
<li>  Teams can get lost in the sprint-by-sprint nature of delivery.  We’ve witnessed teams struggling when they have to integrate with other teams, because they got too focused on their timeline and forgot about the other teams.  I’m implementing a weekly “scrum-of-scrums” with my SCRUM teams, architecture, load &amp; performance testing &amp; infrastructure to ensure we’re engaging them appropriately.</li>
<li>  Some people just can’t handle the teamwork and pace of scrum teams.  Everyone wants to believe they’re a “top dog”, but unfortunately, not everyone can handle it.  You have to spend time developing a personality profile so you know what types of individuals work on your teams.</li>
<li>  Agile doesn’t prevent “death march” projects.  Even with full transparency, there are forces that drive projects into delivering more features than they should.  Quality suffers, people burn out and moral drops.  However, even on these projects, agile works better, because there’s always an end in sight in a few weeks.</li>
</ul>
</div>
<p>So that’s my take after one year of really doing agile.  In the next 12 months, our plans are to gain more consistency across teams (artifacts &amp; ceremonies) and just get better at it.  Organizationally, we’re still newbies, but there’s a real commitment from the top, which makes all the difference.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/89/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=89&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2012/01/22/getting-our-scrum-on-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>
	</item>
		<item>
		<title>New Challenges</title>
		<link>http://kwiebke.wordpress.com/2011/12/21/new-challenges/</link>
		<comments>http://kwiebke.wordpress.com/2011/12/21/new-challenges/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 16:35:09 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/?p=85</guid>
		<description><![CDATA[As I head into the new year, I&#8217;m starting a new role as a Director of App Dev for agile projects. If you&#8217;ve been following along, you should know that I&#8217;ve developed a passion for agile, scrum &#38; xp practices. Moving out of architecture was a tough decision, but I couldn&#8217;t push the engineering teams [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=85&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As I head into the new year, I&#8217;m starting a new role as a Director of App Dev for agile projects.  If you&#8217;ve been following along, you should know that I&#8217;ve developed a passion for agile, scrum &amp; xp practices.  Moving out of architecture was a tough decision, but I couldn&#8217;t push the engineering teams toward xp &amp; tdd from outside the org.</p>
<p>So, to my friends, peers &amp; mentors, what advice do you have for me?  What land mines should I watch out for?  </p>
<p>If you wonder why I&#8217;m posting to a blog instead of Facebook, I&#8217;m keeping work &amp; social networks separate.  LinkedIn, which connects to my blog, is for work &amp; Facebook/Google+ is for friends.  I think mixing work associates into my friend network isn&#8217;t a good idea. </p>
<p>Have a Merry Christmas!  Hope you can enjoy time with friends &amp; family.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/85/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=85&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2011/12/21/new-challenges/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>
	</item>
		<item>
		<title>Prod and Dev Web App Branches</title>
		<link>http://kwiebke.wordpress.com/2011/11/01/prod-and-dev-web-app-branches/</link>
		<comments>http://kwiebke.wordpress.com/2011/11/01/prod-and-dev-web-app-branches/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 13:04:48 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[.net;development]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/2011/11/01/prod-and-dev-web-app-branches/</guid>
		<description><![CDATA[My fellow dotNetters, I need your advice on what should be a simple process that VS 2010 &#38; IIS Express makes complicated.&#160; I&#8217;m trying to keep a production branch and a dev branch on my laptop.&#160; Yes, I know multiple branches are a pain in the butt, but it is a fact of life.&#160; The [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=84&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>My fellow dotNetters, I need your advice on what should be a simple process that VS 2010 &amp; IIS Express makes complicated.&#160; I&#8217;m trying to keep a production branch and a dev branch on my laptop.&#160; Yes, I know multiple branches are a pain in the butt, but it is a fact of life.&#160; </p>
<p>The project is web forms (yes I know that MVC is cooler), VS 2010, IIS Express and SQL Server 2008.&#160; So, I figured this would be an easy process when I do a production release:</p>
<ol>
<li>Check-in code &amp; tag it in subversion </li>
<li>Update my prod code directory from the tagged version in subversion.&#160; Compile app and find what I didn’t check-in correctly.&#160; I call this the oh-sh!t phase. </li>
<li>Apply DB updates from local dev DB to local prod DB.&#160; </li>
<li>Run unit &amp; smoke tests, aka, run nUnit. </li>
<li><strong><font size="2">Problem</font>:&#160; </strong>The web app defined in the solution file &amp; is tied to the port in the IIS Express config file, “C:\Users\[name]\Documents\IISExpress\config\applicationhost.config”.&#160; So, even though there’s 2 separate physical paths on my laptop, the solution file is locked to a port in another config file.&#160; Argh!       <br /> 
<div id="codeSnippetWrapper">
<div style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0;" id="codeSnippet">
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum1">   1:</span> Project(<span style="color:#006080;">&quot;{E24C65DC-...}&quot;</span>) = <span style="color:#006080;">&quot;localhost&quot;</span>, <span style="color:#006080;">&quot;<strong>http://localhost:<u><font size="2">8082</font></u></strong>&quot;</span>, <span style="color:#006080;">&quot;{ACF39ED5-...}&quot;</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum2">   2:</span>     ProjectSection(WebsiteProperties) = preProject</pre>
<p><!--CRLF--></div>
<p>You just have to “learn” that the port # in the solution file magically ties to the port # in the IIS Express config file.&#160; Bleh.&#160; </div>
</li>
</ol>
<p><strong><font color="#808000"><font size="3">So intelligent fellows, how have you solved this situation?</font> </font></strong></p>
<h2>Options that I thought about</h2>
<ol>
<li>Use separate virtual machines – this just seems like overkill.&#160; Why do I need a separate OS per code branch?&#160; I want a more Java-ish solution that doesn’t require configs all over the place; I want a one-stop solution! </li>
<li>Update the solution files – Yuck!&#160; Each time I update the “prod” branch from the tagged prod version, I have to remember to go update the port # in the solution file.&#160; Guess how often this will be forgotten… </li>
<li>Maintain 2 solution files inside the project – Yucky, yuck!&#160; The idea is to keep 2 solutions files; one for dev and one for prod.&#160; Maybe worse than #2, because each time I add another project or other solution item, I have to update the other solution file. </li>
<li><strong><font color="#808000" size="3">Please, please someone have a better idea!!!!!!!</font></strong> </li>
</ol>
<p>&#160;</p>
<h2>What I’m doing now</h2>
<p>I’m using option #2 above and it is painful.&#160; I can test prod fixes in one branch and update the repository (trunk or branch) with the changes.&#160; It isn’t a huge deal to remember to change the port in the solution, but I have to remember to NEVER check-in the prod branch solution file and each time I overwrite it, I have to manually edit it.&#160; There just has to be a cleaner way.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/84/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/84/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/84/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/84/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/84/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/84/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/84/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/84/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/84/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/84/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/84/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/84/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/84/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/84/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=84&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2011/11/01/prod-and-dev-web-app-branches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>
	</item>
		<item>
		<title>A Prettier Cart</title>
		<link>http://kwiebke.wordpress.com/2011/10/17/a-prettier-cart/</link>
		<comments>http://kwiebke.wordpress.com/2011/10/17/a-prettier-cart/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 00:19:35 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[marblespark]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/?p=75</guid>
		<description><![CDATA[We’re making some changes to Marblespark and decided that it was time to clean up an eye sore; our shopping cart.&#160; To be honest, most of the current cart was a quick and dirty implementation that was done late at night.&#160; As you can see, it is ugly, but functional.&#160; Gee, can you tell there’s [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=75&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>We’re making some changes to <a href="http://www.marblespark.com/" target="_blank">Marblespark</a> and decided that it was time to clean up an eye sore; our shopping cart.&#160; To be honest, most of the current cart was a quick and dirty implementation that was done late at night.&#160; As you can see, it is ugly, but functional.&#160; Gee, can you tell there’s an HTML table underneath it.</p>
<p><a href="http://kwiebke.files.wordpress.com/2011/10/cart_current1.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="cart_current" border="0" alt="cart_current" src="http://kwiebke.files.wordpress.com/2011/10/cart_current_thumb1.png?w=520&#038;h=255" width="520" height="255" /></a></p>
<p>&#160;</p>
<p>Phil’s got a great eye at making things look good.&#160; Not me.&#160; I’m a table with boxes and lines, no round corners or any of that fancy schmancy stuff.&#160; Take a look; I think the differences are striking and I was so blown away by the differences that I decided to write this.&#160; Nice clean look; no harsh lines; less text and a nice pretty book cover image. </p>
<p><a href="http://kwiebke.files.wordpress.com/2011/10/cart_new1.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="cart_new" border="0" alt="cart_new" src="http://kwiebke.files.wordpress.com/2011/10/cart_new_thumb1.png?w=526&#038;h=267" width="526" height="267" /></a></p>
<p>In a week or so, I’ll have the site updated with the new cart.&#160; We’re heading into our Christmas rush, so we’ll see if we get more compliments or complaints.&#160; My bet is on compliments.&#160; </p>
<p>What do you think; like the new cart look?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/75/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=75&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2011/10/17/a-prettier-cart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>

		<media:content url="http://kwiebke.files.wordpress.com/2011/10/cart_current_thumb1.png" medium="image">
			<media:title type="html">cart_current</media:title>
		</media:content>

		<media:content url="http://kwiebke.files.wordpress.com/2011/10/cart_new_thumb1.png" medium="image">
			<media:title type="html">cart_new</media:title>
		</media:content>
	</item>
		<item>
		<title>A better search engine</title>
		<link>http://kwiebke.wordpress.com/2011/09/23/a-better-search-engine/</link>
		<comments>http://kwiebke.wordpress.com/2011/09/23/a-better-search-engine/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 13:26:50 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Internet stuff]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/?p=63</guid>
		<description><![CDATA[Don’t stop reading; you probably actually do care about your search engine, but don’t know that you should.  First, give duckduckgo a try as your search engine.  The whole premise behind duckduckgo is that they don’t track your searches or filter your data based on past searches.  Be sure to check out their bank (!) [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=63&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Don’t stop reading; you probably actually do care about your search engine, but don’t know that you should.  First, give <a href="http://duckduckgo.com/" target="_blank">duckduckgo</a> a try as your search engine.  The whole premise behind duckduckgo is that they don’t <a href="http://donttrack.us/" target="_blank">track</a> your searches or <a href="http://dontbubble.us/" target="_blank">filter</a> your data based on past searches.  Be sure to check out their bank (!) syntax; it is pretty handy.  If you’re lazy like me, just give it a try and see if you like it.  If you’re more interested, read on</p>
<h4>Why you should care</h4>
<p><strong>Privacy</strong></p>
<p>Google, Bing and others have this “<em>nice</em>” feature where they send your search terms, location, browser information and other details to a site when you click on a link from their search page.  With enough searching and enough sites tracking you, you’re identity isn’t secret anymore.  Here’s a blurb from WSJ about how insurance companies are thinking of using the data.</p>
<p><a href="http://online.wsj.com/article/SB10001424052748704648604575620750998072986.html" target="_blank">Insurers have long used blood and urine tests to assess people&#8217;s health—a costly process. Today, however, data-gathering companies have such extensive files on most U.S. consumers—online shopping details, catalog purchases, magazine subscriptions, leisure activities and information from social-networking sites—that some insurers are exploring whether data can reveal nearly as much about a person as a lab analysis of their bodily fluids</a></p>
<p>I’m not a big conspiracy person, but I don’t trust folks at Google to take care of my information.  Besides, any organization that hires Eric Schmidt shouldn’t be trusted; he’s a snake.  There&#8217;s just something creepy about him.</p>
<p>Here’s duckduckgo’s <a href="http://donttrack.us/" target="_blank">presentation</a> on the subject.</p>
<p><strong>Filtering your data</strong></p>
<p><strong><em>Wikipedia</em></strong>: <a href="http://en.wikipedia.org/wiki/Filter_bubble">http://en.wikipedia.org/wiki/Filter_bubble</a></p>
<p>While I’m sure we have vast political differences, this is a good presentation on the “filter bubble”.   There&#8217;s a fair amount of disagreement on his views, but it is interesting to listen to his hypothesis.</p>
<object width="446" height="326"><param name="movie" value="http://video.ted.com/assets/player/swf/EmbedPlayer.swf"></param><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always"/><param name="wmode" value="transparent"></param><param name="bgColor" value="#ffffff"></param> <param name="flashvars" value="vu=http://video.ted.com/talk/stream/2011/Blank/EliPariser_2011-320k.mp4&su=http://images.ted.com/images/ted/tedindex/embed-posters/EliPariser-2011.embed_thumbnail.jpg&vw=432&vh=240&ap=0&ti=1091&lang=eng&introDuration=15330&adDuration=4000&postAdDuration=830&adKeys=talk=eli_pariser_beware_online_filter_bubbles;year=2011;theme=a_taste_of_ted2011;theme=what_s_next_in_tech;theme=new_on_ted_com;theme=bold_predictions_stern_warnings;event=Bold+Predictions%2C+Stern+Warnings;tag=Culture;tag=Global+Issues;tag=Technology;tag=journalism;tag=politics;&preAdTag=tconf.ted/embed;tile=1;sz=512x288;" /><embed src="http://video.ted.com/assets/player/swf/EmbedPlayer.swf" pluginspace="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="transparent" bgColor="#ffffff" width="446" height="326" allowFullScreen="true" allowScriptAccess="always" flashvars="vu=http://video.ted.com/talk/stream/2011/Blank/EliPariser_2011-320k.mp4&su=http://images.ted.com/images/ted/tedindex/embed-posters/EliPariser-2011.embed_thumbnail.jpg&vw=432&vh=240&ap=0&ti=1091&lang=eng&introDuration=15330&adDuration=4000&postAdDuration=830&adKeys=talk=eli_pariser_beware_online_filter_bubbles;year=2011;theme=a_taste_of_ted2011;theme=what_s_next_in_tech;theme=new_on_ted_com;theme=bold_predictions_stern_warnings;event=Bold+Predictions%2C+Stern+Warnings;tag=Culture;tag=Global+Issues;tag=Technology;tag=journalism;tag=politics;"></embed></object>
<p>Here’s duckduckgo’s take on it, <a href="http://dontbubble.us/" target="_blank">dontbubble.us</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/63/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=63&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2011/09/23/a-better-search-engine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting our SCRUM on #3</title>
		<link>http://kwiebke.wordpress.com/2011/07/13/getting-our-scrum-on-3/</link>
		<comments>http://kwiebke.wordpress.com/2011/07/13/getting-our-scrum-on-3/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 00:32:19 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/2011/07/13/getting-our-scrum-on-3/</guid>
		<description><![CDATA[So in Part 1, I talked about the development impacts of SCRUM and agile and Part 2 was about methodology impacts.&#160; This post is an update after another 3 months with the methodology. It ROCKS! I know I started off with the same heading last time, but it totally rocks!&#160; We’re 7 months into our [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=62&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So in <a href="http://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-1/" target="_blank">Part 1</a>, I talked about the development impacts of SCRUM and agile and <a href="http://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-2/" target="_blank">Part 2</a> was about methodology impacts.&#160; This post is an update after another 3 months with the methodology.</p>
<h2>It ROCKS!</h2>
<p>I know I started off with the same heading last time, but it totally rocks!&#160; We’re 7 months into our first major SCRUM project and I can tell you that waterfail is now so painful that I can’t stand it.&#160; I’m spread across several projects and I gravitate towards the scrum project, because it is fun.&#160; There’s real teamwork; people working hard and having fun; progress being made and business folks believing in the work.&#160; Who wouldn’t want to work in that environment!</p>
<h2>What I’ve observed lately</h2>
<p><strong><font color="#f79646">Attitude </font></strong></p>
<p>I have to admit that I totally missed what scrum/agile would do for attitude.&#160;&#160; In waterfail, it seems that you’re always fighting between teams and trying to figure out how not to do things.&#160; 6 months into a waterfail project and your talking about descoping work; can it get more miserable than that?</p>
<p>Now contrast the attitude with an agile project and it is the complete opposite.&#160; In agile, it is all about what we can get done; what we can do to add value and “yes”, “yes”, “yes”.&#160; Don’t get me wrong, there are tough decisions, high tension discussions about features, but in the end; it is teamwork and partnership.&#160; Once the team gels and everyone’s on the same page; the positive vibe can’t be hidden.&#160; Other teams will look at you like you’re crazy because you are feeling GOOD.&#160; When’s the last time you saw that vibe in a 3 hour long requirements session; YUCK!</p>
<p><font color="#f79646"><strong>The team became a team</strong></font></p>
<p>Huh, what?&#160; What I mean is that the group of folks put together really became a team.&#160; About 4 to 5 sprints into the project, there was this sudden shift of everyone pulling together; really pulling together.&#160; The team is comprised of folks from 8 different disciplines/areas (.net, java, DB, ba, qa, pm, architecture <em>[me]</em> &amp; business).&#160; Initially, everyone worked well together, but there were these “walls” between us.&#160; The dev guys had differences of opinion about the DB guy and we weren’t really honest when he was in the room; that sort of walls.&#160; Just not really trusting each other and being honest.</p>
<p>One day, it all just changed.&#160; Yes, it really did happen gradually over time as we learned to trust each other, but it was visibly noticeable about sprint 5.&#160; Suddenly, people gathered around to discuss design or other issues.&#160; Everyone talked through how to solve a problem; it wasn’t just dev types; it was <u>everyone</u>.&#160; It wasn’t my solution or her solution; it was <u>our</u> solution.&#160; That’s when the team became a team.&#160; We trust each other; we help out whenever we can and we’ll protect each other to all ends.&#160; Just like in sports; a cohesive team often times beats the better talent, because they work together.&#160;&#160; </p>
<p><strong><font color="#f79646">Artifacts work</font></strong></p>
<p>When we started SCRUM; I really didn’t get the power of the simple artifacts: velocity chart, burn-down chart &amp; burn-up chart.&#160; Whoopie; 3 graphs; who cares.&#160; Well, I was 100% wrong in my attitude.&#160; I learned the power of velocity and burn-up (progress towards the release) when the steering committee for the project was concerned that the team wasn’t delivering enough.&#160; First, we walked through the velocity (points completed per sprint).&#160; For the first 5 sprints, it was 31 points and there was a <u>zero</u> point sprint in there.&#160; The nest 3 sprints the velocity jumped to 70.&#160; That proved to the executives that a major shift in productivity was being sustained.&#160; Closed that issue in 10 minutes; beat that time to solving an issue with directors and VPs!</p>
<p>Second, the burn up chart proved to them that the project was on track and even trending ahead of schedule to deliver what was required for the first release.&#160; Why did they believe the graph?&#160; We just showed them the velocity and that it was increasing.&#160; They could see that every 3 weeks we were tracking progress and they didn’t have to question the numbers.&#160; The proof was right there.&#160; Closed that issue in less that 10 minutes.</p>
<p>The artifacts work; do them; trust them.&#160; </p>
<p><strong><font color="#f79646">Ceremony works</font></strong>&#160;</p>
<p>In SCRUM, there are 4 ceremonies as they are called: sprint planning, daily stand-up, sprint review and sprint retrospective.&#160; Hopefully you know what these are; if not, go look them up.</p>
<p>Our daily stand-up meetings were horrible at first.&#160; We didn’t stick to: “what I’ve completed”, “what I’m working on today” and “what are my impediments”.&#160; The stand-ups should last about 15 minutes and ours was taking a minimum of 30.&#160; We’ve made it a point to stick to the 3 question and get done in 15 minutes.&#160; Wow, does it go fast; people know what’s going on and everyone’s back to work quickly.&#160; We reserve an additional 15 minutes for issue resolution, but if you’re not need or interested; back to work you go.&#160; Quick, clean, simple and very effective.&#160; </p>
<p>Sprint reviews are your time to show off what you’ve done.&#160; Knowing that business stakeholders, directors, VPs and even “C” level execs are invited and show up really keeps you on your toes.&#160; Do you want to tell them we don’t have a review, because we didn’t complete anything?&#160; I know we don’t.&#160; The power of showing the product every 3 weeks can’t be underestimated.&#160; Ideas start flowing; people get excited and the engineers get to actually talk to real live people on the business side.&#160; When a top level exec shows up at a review; it is amazing how energized the team becomes.&#160; How often does the President of your company show up to your project meetings?</p>
<p>The retrospective has become my favorite meeting for selfish reasons.&#160; We’ve kept every retro’s output on large sheets.&#160; Looking back sprint by sprint at what we’ve done well and what we can improve upon is amazing.&#160; I’ve learned so much about human behavior from this one activity.&#160; Once the team becomes a team and is honest about what’s working and what’s not; real change happens.&#160; Most companies do a mid-year and annual performance review for people.&#160; Imagine if every 3 weeks you looked at your work and really evaluated it; think how different your work habits would be.&#160; It is very, very hard to be honest, open minded and willing to accept real criticism of one’s work.&#160; However, the growth that comes out of this exercise is truly amazing.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/62/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=62&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2011/07/13/getting-our-scrum-on-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>
	</item>
		<item>
		<title>My own CODESOD moment</title>
		<link>http://kwiebke.wordpress.com/2011/06/21/my-own-codesod-moment/</link>
		<comments>http://kwiebke.wordpress.com/2011/06/21/my-own-codesod-moment/#comments</comments>
		<pubDate>Wed, 22 Jun 2011 01:25:26 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/2011/06/21/my-own-codesod-moment/</guid>
		<description><![CDATA[If you’re not familiar with CODESOD (Code Snipped Of the Day), then don’t read on; you won’t get this.&#160; Geek humor isn’t that funny, unless you’re a geek.&#160; I’ve been battling a weird error that happens only during load on MarbleSpark.com.&#160; So yes, we all know what that means; a dreaded “multi-threading bug”.&#160; So, one [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=60&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you’re not familiar with <a href="http://thedailywtf.com/Series/CodeSOD.aspx" target="_blank">CODESOD</a> (Code Snipped Of the Day), then don’t read on; you won’t get this.&#160; Geek humor isn’t that funny, unless you’re a geek.&#160; I’ve been battling a weird error that happens only during load on <a href="http://www.marblespark.com" target="_blank">MarbleSpark.com</a>.&#160; So yes, we all know what that means; a dreaded “multi-threading bug”.&#160; So, one night I got sick and tired of the humiliation of this issue and decided to stay up until I found it!&#160; How hard could it be; it was my code after all.&#160; So, by 1am in the morning, I was bleary-eyed and called it a night.&#160; I was defeated.&#160; The next day, I was walking down a hallway when my “ah ha” moment happened.&#160; Commented one line of code and bata-bing, bata-boom; problem solved.&#160; So here’s my embarrassing code; feel free to snicker at my stupidity!</p>
<h4>Gory Details</h4>
<p>Each page in a book is rendered using either a common page handler or a “specialized” page handler.&#160; I use a config (xml) file that contains entries like the following to wire-up the specialized pages.</p>
<pre class="code"><span style="color:blue;">&lt;</span><span style="color:#a31515;">add </span><span style="color:red;">key</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">mapgraphic</span>&quot;   <span style="color:red;">value</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">klw.Render.Data.PageMapDataHandler</span>&quot; <span style="color:blue;">/&gt;
</span></pre>
<p>&#160;</p>
<p>So, the natural thing to do is hide the ugly details behind a factory class and that’s where my problem hid undetected for years.</p>
<p>&#160;</p>
<p>So let’s see if you can find the bug in an asp.net application, which is naturally multi-threaded.</p>
<p>Look at this code snippet:</p>
<div id="codeSnippetWrapper">
<div style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0;" id="codeSnippet">
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum1">   1:</span> <span style="color:#0000ff;">if</span> (cache.ContainsKey(key))</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum2">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum3">   3:</span>     result = cache[key];</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum4">   4:</span> }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum5">   5:</span> <span style="color:#0000ff;">else</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum6">   6:</span> {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum7">   7:</span>     <span style="color:#0000ff;">if</span> ((PageData.SpecializeKey != <span style="color:#0000ff;">null</span>) &amp;&amp; (lookupTable.ContainsKey(PageData.SpecializeKey)))</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum8">   8:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum9">   9:</span>         Type handlerType = lookupTable[PageData.SpecializeKey];</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum10">  10:</span>         result = Activator.CreateInstance(handlerType) <span style="color:#0000ff;">as</span> PageDataHandler;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum11">  11:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum12">  12:</span>     <span style="color:#0000ff;">else</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum13">  13:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum14">  14:</span>         result = <span style="color:#0000ff;">new</span> PageDataHandler();</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum15">  15:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum16">  16:</span>     result = Activator.CreateInstance(handlerType) <span style="color:#0000ff;">as</span> PageDataHandler;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum17">  17:</span>     cache[key] = result;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum18">  18:</span> }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;font-family:&#039;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum19">  19:</span> <span style="color:#0000ff;">return</span> result;</pre>
<p><!--CRLF--></div>
</div>
<p>&#160;</p>
<p>Did you find it?&#160; Ok, I’ll give you a hint; what happens if there’s class level state for anything created in line 10 or 14?&#160; Look a little further down.&#160; Did you find it?</p>
<p>&#160;</p>
<p>Okay, times up.&#160; My CODESOD moment is line #17.&#160; I really meant to cache the “Type”, NOT the instance for “specialized” pages.&#160; So there’s my multiple threading issue.&#160; If multiple threads are requesting an instance at about the same time, thread 2 can get the instance that thread 1 is using.&#160; Bunch of thread switching and bad things happen.&#160; I was in a hurry, so I just commented line 17 and the problem went away.&#160; </p>
<p>&#160;</p>
<p>There you have it; enjoy my folly. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/60/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=60&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2011/06/21/my-own-codesod-moment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting some SCRUM on Part 2</title>
		<link>http://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-2/</link>
		<comments>http://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-2/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 02:26:55 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-2/</guid>
		<description><![CDATA[So in Part 1, I talked about the development impacts of SCRUM and agile.&#160; In this part, I’m going to discuss what we’re seeing from a project methodology impact. It ROCKS! As surprised as I was about the impacts of SCRUM and agile on development, I’m even more surprised about the impact it has on [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=58&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So in <a href="http://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-1/" target="_blank">Part 1</a>, I talked about the development impacts of SCRUM and agile.&#160; In this part, I’m going to discuss what we’re seeing from a project methodology impact. </p>
<h2>It ROCKS!</h2>
<p>As surprised as I was about the impacts of SCRUM and agile on development, I’m even more surprised about the impact it has on project delivery.&#160; Now, to be clear, SCRUM doesn’t cover the entire lifecycle; SCRUM is about getting quality code out the door.&#160; Some will disagree with this, but SCRUM doesn’t cover business valuation of the project, what happens after it is released, call center impacts, etc..&#160; There are additional agile project management approaches that do.&#160; Read <a href="http://www.amazon.com/Agile-Project-Management-Creating-Innovative/dp/0321658396/ref=cm_cr_pr_product_top" target="_blank">this book</a>; I can’t cover the material as well as the authors did.&#160; </p>
<p>&#160;</p>
<h2>Getting Rid of the Bureaucracy</h2>
<p>The biggest problem with the waterfail methodology is it inherently adds a lot of paperwork, sign-offs, meetings and a ton of bureaucracy.&#160; SCRUM and agile is all about doing the least amount necessary to produce a quality product.&#160; If I never see another 3 ring binder full of what’s called requirements, I’ll be a happy, happy man.&#160; So how does SCRUM achieve this?&#160; Well, by applying common sense:</p>
<li><strong><font color="#ff8000">Co-locate people – </font></strong>Get all of the necessary people in a room or general area and have them work together to solve the problem.&#160; If there’s a question, walk over to the person and ask them them the question.&#160; How simple is that! </li>
<li><strong><font color="#f79646">Empower the people – </font></strong>You’ve hired your employees because you think they are smart enough to get the job done.&#160; <strong>SO, LET THEM!</strong>&#160; This doesn’t mean they have free reign to do everything they want; there are rules and guidelines after all. </li>
<li><strong><font color="#f79646">No extra meetings – </font></strong>Co-locating and empowering the people helps tremendously.&#160; Eliminating 2 hours of meetings a day doesn’t sound like much until you realize that you’ve added another work day back into the week.&#160; You’re probably getting 2 maybe 3 work days in a week; adding another is a huge productivity boost.&#160; Don’t believe my numbers, track what you do for a few weeks and see how many hours are really productive. </li>
<li><strong><font color="#f79646">2 – 4 week deliverables – </font></strong>results in immediate feedback, immediate reprioritization and laser focus on what’s important.&#160; Forget the fluff; you don’t have time. </li>
<li><strong><font color="#f79646">Eliminate change control –</font></strong> <strong>What!!!!&#160; Are you crazy, you can’t do that.</strong>&#160; Well, that’s exactly what you do.&#160; Embrace change; that’s what happens in a project; don’t try to fight it.&#160; Instead of change control, you keep a running list of work in <strong>force ranked </strong>order.&#160; Yes, you have to force rank it; there is 1 and ONLY 1 top priority.&#160; You have the chance every 2 – 4 weeks to change priority and the business <strong>loves, loves, loves</strong> it.&#160; </li>
<li><strong><font color="#f79646">You won’t do everything –</font></strong> Guess what, you’ll never get to the things at the bottom of the backlog.&#160; Shhh, this is our little secret, don’t tell the business folks.&#160; By the time your 6 – 8 months into a project, your list will be dramatically different than when you started.&#160; Once you get towards the tasks at the bottom, there will be a new higher priority project and off you go.&#160; Stuff at the bottom eventually is just thrown away or handed off to a maintenance group.&#160; Enjoy. </li>
<li>
<div align="left"><strong><font color="#f79646">Eliminate the requirements binder –</font></strong> <strong>Now I’ve really gone too far; haven’t I.</strong>&#160; Once again no, no, no.&#160; I’m not saying that you don’t write down what needs to be done, but you don’t have to write down every last little detail, such as “button 127 is 26 pixels from, blah, blah”.&#160; Besides, no one reads and understands a 100 page requirements document.&#160; Since you are sitting next to each other, here’s a novel idea; stand up; ask the QA, BA and business person to step over to the whiteboard and scribble out what needs to be done.&#160; Yup, 3 weeks of meetings boiled down to an hour on a whiteboard.&#160; Now, for compliance reasons, you’ll have to track this, so do that, but don’t track every little detail.</div>
<ul>
<h2>
<ul>You Can’t Hide the Truth</ul>
</h2>
<p> In scrum, it is simple; you track what’s planned for the next release (2 – 4 weeks), what’s in progress, what’s in testing and what’s done.&#160; For each sprint, you track the work that’s remaining (burn down chart).&#160; Every day, you determine how much work is left on your task and the points/hours are tracked.&#160; Within a few days, you can see if you’ve taken on too much work.&#160; After a few sprints, what you end up with is <a href="http://www.scrumalliance.org/articles/39-glossary-of-scrum-terms" target="_blank">velocity</a>.&#160; Once you know your velocity and you know how many points you can do in a sprint, it is easy to see how much work you can get done by when.&#160; Dedicating people to a project lets you know exactly how much you are spending every week or month.&#160; Tie these two facts together, add in capital spending and you can quickly calculate the cost of the project.&#160; Simple math; not Enron math.</ul>
<ul>Brutal honestly is a key part of SCRUM.&#160; Daily you track progress, every few weeks you show what you’ve done and weekly you track spend.&#160; There’s no hiding where you are if you are honest.&#160; Weaker developers are easy to spot in a scrum project.&#160; Each developer picks the tasks and works them.&#160; With pair programming, qa defect tracking and points completed, the weaker ones stand out.&#160; This leaves you with two options; help the weaker developers improve their skills or replace them.&#160; Sounds harsh, but you can’t carry dead weight if you want a quality product.&#160; Let’s face it, we all know the developers that are assigned to waterfail projects that are hidden.&#160; It is easy in waterfall, because they can take a week task and drag it out for months.&#160; Those days are gone in SCRUM.&#160; What I never understood is why these people are allowed to hang on and drag down one project after another.&#160; Brutal honesty; they can’t hide.</ul>
<p>Finally, at the end of each sprint (2 – 4 week release), you show off what you’ve done.&#160; Hey, we all like to show off and it is fun to see the users reactions.&#160; What we’ve seen happen is that once they see the screens, 5 more things come to their mind.&#160; They take these ideas, look at the prioritized work and inject them where they need to be.&#160; The users feel so empowered that they don’t want to miss a demo.&#160; You can’t believe how powerful this simple practice is.&#160; Plus, there’s no hiding what didn’t get done, what looks bad or what’s broken. </p>
<h2>How To Get Started</h2>
<p>This is the hard part.&#160; If it is so great, why doesn’t every CIO, CTO and VP in the IT organization jump on the bandwagon and demand that we get scrum’n?&#160; Well, they are usually focusing on other things, like that latest prod issue that’s costing a few hundred thousand dollars a day.&#160; Now you’re thinking, “Cool, we’ll start a grass roots movement and they’ll be forced to do this once they see how wonderful it is and how brilliant I am.”&#160; Nope, that’ll get you part way there, extremely frustrated and the target of senior management’s anger.&#160; I don’t have the silver bullet, but here’s how we’ve started and been pretty darn successful:</p>
<ul>
<li><font color="#f79646"><strong>Top down support </strong>– </font>If your C’s and VP’s aren’t onboard, then don’t try.&#160; I’m serious, don’t try or you’ll end up miserable and frustrated.&#160; Take your time, present a coherent argument in terms that they care about: costs, transparency, discipline and productivity.&#160; If you speak about sprints, burn down charts, burn up charts and backlogs, you just as well save your breath; they don’t care about this stuff.&#160; They want to know what’s going to reduce spend, improve quality and reduce time to market.&#160; They will absolutely love it if they don’t hear the business folks say “That’s what I asked for, but that’s not what I wanted” ever again. </li>
<li><font color="#f79646"><strong>Bottom up support </strong>– </font>yes, you need to have support from the folks in the trenches.&#160; You’ll find a number of engineers and lower level managers that won’t support SCRUM.&#160; The brutal honesty and simplicity of the methodology just won’t fly in their minds.&#160; You need to talk to your peers, let them borrow your books and evangelize.&#160; Don’t get too crazy before you engage upper management or you’ll be in deep doo doo. </li>
<li><strong><font color="#f79646">Training – </font></strong>Once you’ve got management onboard, you have to get people trained.&#160; Don’t try to figure it out on your own.&#160; Reading books and blogs is good, but they can’t answer your questions like a trainer can.&#160; Get the folks that will be part of the first few projects and get them trained.&#160; Scrum Master training is an excellent start. </li>
<li><strong><font color="#f79646">Train management &amp; the business– </font></strong>yes, you have to get them to training.&#160; You need their support and they need to learn all the new lingo and what to expect.&#160; Most of your leaders are there, because they are smart people.&#160; Most trainers provide a 1/2 day management training and it is invaluable.&#160; If they won’t go to training, don’t proceed.&#160; SCRUM isn’t just an IT thing; it is a way of thinking. </li>
<li><strong><font color="#f79646">Coaching – </font></strong>don’t, don’t don’t try to go it alone.&#160; Hire someone to be a coach.&#160; I thought after training that I knew how “this scrum thing works”, but deep down, I knew that we needed more help.&#160; I knew just enough to be dangerous and not enough to be useful.&#160; Having a coach there to guide the business, management and the dev teams is some of the best money we spent.&#160; Someone from outside of your organization can provide honest feedback that can’t be easily said from people inside the organization.&#160; Get yourself a coach and GO TEAM! </li>
<li><strong><font color="#f79646">Reading – </font></strong>do it all the time, don’t stop and learn, learn, learn.&#160; SCRUM is a mindset, not a set of rules.&#160; See what’s worked for others and what hasn’t.&#160; As soon as you think you are done, you aren’t. </li>
<li><strong><font color="#f79646">Start Small – </font></strong>don’t try to boil the ocean.&#160; Pick one or two key projects, train the teams and get started.&#160; Don’t pick a couple of loser projects; you want the high important ones that will get funding and attention.&#160; Don’t try to move the entire org overnight to SCRUM or you’ll never succeed.&#160; What we are seeing is that after a few months, it will be hard enough to contain scrum.&#160; Start small and let it build over time.&#160; Yes, there are testimonials about changing the entire organization; good for them.&#160; I wouldn’t recommend it. </li>
</ul>
<h2>Summary</h2>
<p>I guess the best advice I can offer is don’t wait.&#160; Start doing some research, find one or two upper management folks that will listen and get the ball rolling.&#160; </p>
<p>No, “waterfail” isn’t a typo.&#160; If 80% of all waterfail projects fail, how can it be called anything else!&#160; SCRUM succeeds by going back to the basics:&#160; small teams tackling one thing; simple math to track progress and brutal honesty about all facets.</p>
<p>Be prepared for a lot of hard work resistance and hard lessons learned.&#160; You aren’t going to get it right the first time.&#160; You’ll have to be Darwinian and adapt and change based on the environmental forces around you.&#160; We’re not rock’n and roll’n completely; we’re pretty new to this and learning.&#160; I’m 100% convinced that I won’t be writing a blog post about how SCRUM failed.&#160; I see a lot of success in our future.</p>
<p>&#160;</p>
<h2>References</h2>
<p>These are people and sights that I use; these aren’t the first picks from a google or bing search:</p>
<ul>
<li><a title="http://lucamackenzie.com/Home_Page.html" href="http://lucamackenzie.com/Home_Page.html">http://lucamackenzie.com/Home_Page.html</a> </li>
<li><a title="http://www.scrumalliance.org/profiles/9-bob-schatz" href="http://www.scrumalliance.org/profiles/9-bob-schatz">http://www.scrumalliance.org/profiles/9-bob-schatz</a>, <a title="http://www.agileinfusion.com/" href="http://www.agileinfusion.com/">http://www.agileinfusion.com/</a> </li>
<li><a title="http://www.scrumalliance.org/profiles/31-jim-schiel" href="http://www.scrumalliance.org/profiles/31-jim-schiel">http://www.scrumalliance.org/profiles/31-jim-schiel</a> </li>
<li><a title="http://www.scrumalliance.org/profiles/87-james-n-smith" href="http://www.scrumalliance.org/profiles/87-james-n-smith">http://www.scrumalliance.org/profiles/87-james-n-smith</a>, <a title="http://www.winnowmanagement.com/" href="http://www.winnowmanagement.com/">http://www.winnowmanagement.com/</a> </li>
</ul>
</li>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/58/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=58&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting some SCRUM on Part 1</title>
		<link>http://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-1/</link>
		<comments>http://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-1/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 00:36:46 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-1/</guid>
		<description><![CDATA[Unless you’ve been under a rock for the last 5 years, you’ve heard about agile, xp, scrum and a bunch of other strange buzzwords.&#160; Personally, I’m about 5 months into my first real hands-on experience with scrum and agile and here’s what I’ve learned so far.&#160; Remember, your mileage may vary! It ROCKS! I rarely [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=56&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Unless you’ve been under a rock for the last 5 years, you’ve heard about agile, xp, scrum and a bunch of other strange buzzwords.&#160; Personally, I’m about 5 months into my first real hands-on experience with scrum and agile and here’s what I’ve learned so far.&#160; Remember, your mileage may vary!</p>
<h2>It ROCKS!</h2>
<p>I rarely get excited about project development approaches, but SCRUM and agile just plain rock.&#160; We are seeing dramatic changes from a project management perspective and a development perspective.&#160; Honestly, seeing it in action is 10x more impressive than reading testimonials or “how-to” books.&#160; I wish they would have called it “Common Sense Approach” instead of SCRUM, but oh well.</p>
<h2>Development Impacts</h2>
<h3>Quality</h3>
<p>Our #1 development priority is quality.&#160; Not features, not time to deliver, but quality.&#160; To achieve this, we’re spending significant effort building automated unit tests.&#160; Everyone thinks they know how to build automated unit tests, but until you do it, you won’t appreciate the complexity. </p>
<p>The first step is to make unit testing one of the most important steps in you dev effort.&#160; To do this, we approach building our app as follow:</p>
<ol>
<li>Build the entities (we’re using nHibernate) </li>
<li>Build out the repository/data access (crud operations, searches, etc.) </li>
<li>Build the unit test (lots of them) </li>
<li>Finally, build the UI or services </li>
</ol>
<ol>By sticking to this approach we’re pretty much guaranteeing that business logic stays out of the UI.&#160; Duh, of course “we do that”, but be honest, how many times does a little business logic leak into the UI.&#160; Yeah, I thought so.&#160; Some may argue to unit test the entities, but they are just to hold data, so there’s nothing much to test.</ol>
<p>Good unit test are hard to write; there’s books written on the subject.&#160; Here’s what we’re doing:</p>
<ol>
<li>Full CRUD operational tests.&#160; Using an ORM, you’ll find a few WTF moments after looking at the generated SQL.&#160; While we don’t automate looking for the WTF SQL, creating the unit tests and logging the SQL makes it real easy to spot.&#160; Besides, it is good practice to ensure that our data access can perform the basic CRUD operations.</li>
<li>Test the various search operations with varying parameters.&#160; Test with valid and invalid parameter; test several boundary cases and throw in a few “gut feel’ tests.&#160; You’d be surprise at how many gut feel tests discover the hard problems.</li>
<li>When we find a bug in QA or in UI testing, stop immediately, write a unit test that covers the bug; fix the code and you’re golden.&#160; </li>
<li>A few other rules that are just good unit testing practices:
<ol>
<li>Guarantee that each test can be run independent of the other tests. </li>
<li>Guarantee that all tests can be run in any order. </li>
<li>Do your best to construct your own test data; don’t rely on pre-existing data.&#160; All good frameworks have test setup and destroy (tear down) methods; use them!</li>
<li>When you need large amounts of data for a test, such as data paging tests, either bulk load data before your tests or pick a range of data in your DB and tell everyone to LEAVE IT ALONE.&#160; TDD purist; back off; I know that you can test without the DB and it is overhead, blah, blah.&#160; In my world, keeping a few hundred thousand rows in the DB is a much easier approach.&#160; </li>
<li>Find tools that will help generate the test code.&#160; We’re just starting to investigate this and are looking at T4 templates, MyGeneration and other tools. <strong>Let me know if you’ve got a good one.</strong> </li>
</ol>
</li>
<li>Each test should do ONE and ONLY ONE thing.&#160; Don’t try to test all the crud operations in one test; you’re just wasting your time. </li>
<li>We are NOT following full test driven development (TDD).&#160; We’re making some first steps and hope to get there eventually. </li>
</ol>
<ol>All the rest of SCRUM and Agile/XP approaches are very valuable, but I’m finding this to be the most valuable.&#160; If you’re not ready to dive head-long into full SCRUM and agile, take up automated unit testing.&#160; And while your at it, help your QA team to automate their testing.&#160; </ol>
<h3>Other Benefits</h3>
<ul>
<li>Reduces the ever growing boat anchor effect.&#160; By this I mean that as you add features, you have to regression test, which becomes a bigger burden, aka boat anchor.&#160; Automated unit tests is insurance against the boat anchor and introducing bugs.&#160; Make changes, add unit tests, re-run ALL tests and when everything is green, you know that you didn’t break anything.</li>
<li>The ability to refactor your code and really trust that you haven’t broken anything is enormous.&#160; Change a few classes, run the test, all checkmarks turn green.&#160; DONE!&#160; Eliminating code debt over time provides tremendous payback in the long run.</li>
</ul>
<p>My final word on automated unit tests is that your comfort level in not breaking things is ONLY as good as the tests you write.&#160; And you can’t test everything and you will leave a few holes.&#160; However, the benefits so far outweigh the time commitment that you should start now.</p>
<p>&#160;</p>
<h3>Small Chunks of Work</h3>
<p>The second piece of SCRUM and agile that is dramatically changing how we work is breaking down the work into little pieces and getting them to QA quickly.&#160; Honestly, this is just how I work anyway, so it wasn’t a change for me.&#160; I’ve always tackled things one screen at a time or one business function at a time, so this just works.&#160; </p>
<p>We’re finding that breaking tasks into 6 hour chunks works really well.&#160; Knowing that something needs to be done by tomorrow is a huge motivator.&#160; As an example, day one may be add a new page skeleton, including CSS and style.&#160; Day 2, add basic functionality.&#160; Day 3 add ajax and fancy UI (jquery anyone) transitions.&#160;&#160; </p>
<p>Study after study has shown that tackling three tasks in a row is far faster than tacking all three at once.&#160; It takes an average of 30 – 45 minutes for you to get back into the groove, so stick to one thing, do it right and get-r-done.</p>
<p>&#160;</p>
<h3>Final Thoughts</h3>
<p>There’s a lot more to agile than I can cover, know or am experienced enough to discuss.&#160; Here’s a few other key points to consider/research:</p>
<ul>
<li>Pair programming – I thought this was the biggest waste of time on the planet when I first heard of it.&#160; However, if you have one engineer focus on the unit tests while the other is building the entities or repository classes; BINGO!&#160; They will refactor on the fly, discuss problems as they arise and generally you’ll get far better code.&#160;&#160; </li>
<li>Continuous Integration – Just DO IT!&#160; It is hard work, takes a lot of discipline, but is well worth it.&#160; Java has had it for a long time and .NET is starting to catch up.&#160; Just do it; really! </li>
<li>Check-in code frequently – If you break work into 6 hour chunks, there’s no reason for code to be sitting on an engineers workstation.&#160; Check it in, so we can all see what’s changing; no more secrets. </li>
<li>Try things; break things; it is YOUR TEAM, so do what works best for you. </li>
</ul>
<h2>Project Methodology Impacts </h2>
<p>I’ll cover our initial experiences in Part 2.</p>
<h2>References</h2>
<p><a title="http://www.extremeprogramming.org/rules/unittests.html" href="http://www.extremeprogramming.org/rules/unittests.html">http://www.extremeprogramming.org/rules/unittests.html</a>     <br /><a title="http://www.scrumalliance.org/" href="http://www.scrumalliance.org/">http://www.scrumalliance.org/</a>     <br /><a title="http://www.testdriven.com/" href="http://www.testdriven.com/">http://www.testdriven.com/</a>     <br /><a title="http://www.methodsandtools.com/archive/archive.php?id=103" href="http://www.methodsandtools.com/archive/archive.php?id=103">http://www.methodsandtools.com/archive/archive.php?id=103</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/56/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=56&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2011/03/13/getting-some-scrum-on-part-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>
	</item>
		<item>
		<title>Website Log Tail</title>
		<link>http://kwiebke.wordpress.com/2010/12/19/website-log-tail/</link>
		<comments>http://kwiebke.wordpress.com/2010/12/19/website-log-tail/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 02:29:32 +0000</pubDate>
		<dc:creator>kwiebke</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[marblespark]]></category>

		<guid isPermaLink="false">https://kwiebke.wordpress.com/2010/12/19/website-log-tail/</guid>
		<description><![CDATA[One of the downsides of our shared hosting plan is that we don’t have any access to the box, except for FTP. Marblespark.com uses log4net extensively and the logs are used to track all sorts of things. Since I don’t have any type of RDP or other terminal access to the server, I needed something [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=45&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of the downsides of our shared hosting plan is that we don’t have any access to the box, except for FTP.  <a href="http://www.marblespark.com/" target="_blank">Marblespark.com</a> uses <a href="http://logging.apache.org/log4net/" target="_blank">log4net</a> extensively and the logs are used to track all sorts of things.  Since I don’t have any type of RDP or other terminal access to the server, I needed something to view the logs.</p>
<h3><span style="color:#ff8000;">First Attempt</span></h3>
<p>The first attempt was a very, very basic asp.net page with a drop down for the log files, a text box for number of lines to read, a text area to display the lines and one button “View Log”.  Seemed very simple, until I needed to read a log file that was already opened for writing.</p>
<pre class="code">fs = <span style="color:blue;">new </span><span style="color:#2b91af;">FileStream</span>(path, <span style="color:#2b91af;">FileMode</span>.Open, <span style="color:#2b91af;">FileAccess</span>.Read, <span style="color:#2b91af;">FileShare</span>.ReadWrite);</pre>
<p>Next, I needed a way to read a file backward.  Gee, how hard can that be…  Luckily, I was able to find the code (forgot where) and here’s the guts of it.  Search on c# backward reader and you’ll find it.</p>
<div id="codeSnippetWrapper" style="text-align:left;line-height:9pt;background-color:#f4f4f4;width:97.5%;height:300px;white-space:nowrap;overflow:auto;">
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum1" style="color:#606060;">   1:</span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> Readline()</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum2" style="color:#606060;">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum3" style="color:#606060;">   3:</span>     <span style="color:#0000ff;">byte</span>[] line;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum4" style="color:#606060;">   4:</span>     <span style="color:#0000ff;">byte</span>[] text = <span style="color:#0000ff;">new</span> <span style="color:#0000ff;">byte</span>[1];</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum5" style="color:#606060;">   5:</span>     <span style="color:#0000ff;">long</span> position = 0;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum6" style="color:#606060;">   6:</span>     <span style="color:#0000ff;">int</span> count;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum7" style="color:#606060;">   7:</span>     fs.Seek(0, SeekOrigin.Current);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum8" style="color:#606060;">   8:</span>     position = fs.Position;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum9" style="color:#606060;">   9:</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum10" style="color:#606060;">  10:</span>     <span style="color:#008000;">//do we have trailing \r\n?</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum11" style="color:#606060;">  11:</span>     <span style="color:#0000ff;">if</span> (fs.Length &gt; 1)</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum12" style="color:#606060;">  12:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum13" style="color:#606060;">  13:</span>         <span style="color:#0000ff;">byte</span>[] vagnretur = <span style="color:#0000ff;">new</span> <span style="color:#0000ff;">byte</span>[2];</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum14" style="color:#606060;">  14:</span>         fs.Seek(-2, SeekOrigin.Current);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum15" style="color:#606060;">  15:</span>         fs.Read(vagnretur, 0, 2);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum16" style="color:#606060;">  16:</span>         <span style="color:#0000ff;">if</span> (ASCIIEncoding.ASCII.GetString(vagnretur).Equals(<span style="color:#006080;">"\r\n"</span>))</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum17" style="color:#606060;">  17:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum18" style="color:#606060;">  18:</span>             <span style="color:#008000;">//move it back</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum19" style="color:#606060;">  19:</span>             fs.Seek(-2, SeekOrigin.Current);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum20" style="color:#606060;">  20:</span>             position = fs.Position;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum21" style="color:#606060;">  21:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum22" style="color:#606060;">  22:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum23" style="color:#606060;">  23:</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum24" style="color:#606060;">  24:</span>     <span style="color:#0000ff;">while</span> (fs.Position &gt; 0)</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum25" style="color:#606060;">  25:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum26" style="color:#606060;">  26:</span>         text.Initialize();</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum27" style="color:#606060;">  27:</span>         <span style="color:#008000;">//read one char</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum28" style="color:#606060;">  28:</span>         fs.Read(text, 0, 1);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum29" style="color:#606060;">  29:</span>         <span style="color:#0000ff;">string</span> asciiText = ASCIIEncoding.ASCII.GetString(text);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum30" style="color:#606060;">  30:</span>         <span style="color:#008000;">//moveback to the charachter before</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum31" style="color:#606060;">  31:</span>         fs.Seek(-2, SeekOrigin.Current);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum32" style="color:#606060;">  32:</span>         <span style="color:#0000ff;">if</span> (asciiText.Equals(<span style="color:#006080;">"\n"</span>))</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum33" style="color:#606060;">  33:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum34" style="color:#606060;">  34:</span>             fs.Read(text, 0, 1);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum35" style="color:#606060;">  35:</span>             asciiText = ASCIIEncoding.ASCII.GetString(text);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum36" style="color:#606060;">  36:</span>             <span style="color:#0000ff;">if</span> (asciiText.Equals(<span style="color:#006080;">"\r"</span>))</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum37" style="color:#606060;">  37:</span>             {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum38" style="color:#606060;">  38:</span>                 fs.Seek(1, SeekOrigin.Current);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum39" style="color:#606060;">  39:</span>                 <span style="color:#0000ff;">break</span>;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum40" style="color:#606060;">  40:</span>             }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum41" style="color:#606060;">  41:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum42" style="color:#606060;">  42:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum43" style="color:#606060;">  43:</span>     count = <span style="color:#0000ff;">int</span>.Parse((position - fs.Position).ToString());</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum44" style="color:#606060;">  44:</span>     line = <span style="color:#0000ff;">new</span> <span style="color:#0000ff;">byte</span>[count];</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum45" style="color:#606060;">  45:</span>     fs.Read(line, 0, count);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum46" style="color:#606060;">  46:</span>     fs.Seek(-count, SeekOrigin.Current);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum47" style="color:#606060;">  47:</span>     <span style="color:#0000ff;">return</span> ASCIIEncoding.ASCII.GetString(line);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum48" style="color:#606060;">  48:</span> }</pre>
<p><!--CRLF--></p>
</div>
<p>So, to read an open log file and dump it to the text area:</p>
<div id="codeSnippetWrapper" style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:97.5%;height:300px;overflow:auto;white-space:nowrap;">
<div id="codeSnippet" style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;">
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum1" style="color:#606060;">   1:</span> <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">void</span> Button1_Click(<span style="color:#0000ff;">object</span> sender, EventArgs e)</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum2" style="color:#606060;">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum3" style="color:#606060;">   3:</span>     tbData.Text = <span style="color:#006080;">""</span>;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum4" style="color:#606060;">   4:</span>     <span style="color:#0000ff;">int</span> lineCnt = 1;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum5" style="color:#606060;">   5:</span>     List&lt;<span style="color:#0000ff;">string</span>&gt; lines = <span style="color:#0000ff;">new</span> List&lt;<span style="color:#0000ff;">string</span>&gt;();</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum6" style="color:#606060;">   6:</span>     <span style="color:#0000ff;">int</span> maxLines = <span style="color:#0000ff;">int</span>.Parse(tbLines.Text);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum7" style="color:#606060;">   7:</span>     <span style="color:#0000ff;">string</span> logFile = Server.MapPath(<span style="color:#006080;">"~/"</span> + ddlLogFiles.SelectedItem.ToString());</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum8" style="color:#606060;">   8:</span>     BackwardReader br = <span style="color:#0000ff;">new</span> BackwardReader(logFile);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum9" style="color:#606060;">   9:</span>     tbData.Text = <span style="color:#006080;">""</span>;     <span style="color:#0000ff;">while</span> (!br.SOF)</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum10" style="color:#606060;">  10:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum11" style="color:#606060;">  11:</span>         <span style="color:#0000ff;">string</span> line = br.Readline();</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum12" style="color:#606060;">  12:</span>         lines.Add(line + System.Environment.NewLine);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum13" style="color:#606060;">  13:</span>         <span style="color:#0000ff;">if</span> (lineCnt == maxLines) <span style="color:#0000ff;">break</span>;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum14" style="color:#606060;">  14:</span>         lineCnt++;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum15" style="color:#606060;">  15:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum16" style="color:#606060;">  16:</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum17" style="color:#606060;">  17:</span>     <span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = lines.Count; i &gt; 0; i--)</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum18" style="color:#606060;">  18:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum19" style="color:#606060;">  19:</span>         <span style="color:#0000ff;">this</span>.tbData.Text += lines[i - 1];</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum20" style="color:#606060;">  20:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum21" style="color:#606060;">  21:</span> }</pre>
<p><!--CRLF--></p>
</div>
</div>
<p>Initially, this worked well for a while, but I got tired of clicking “View Log” over and over and realized that I wanted a web based Tail program, like <a href="http://baremetalsoft.com/baretail/" target="_blank">Baretail</a>, which I use on my laptop.</p>
<h3><span style="color:#ff8000;"> </span></h3>
<h3><span style="color:#ff8000;">Second Attempt</span></h3>
<p>My next attempt was to simply use javascript’s setTimeout to refresh the page.  While this worked, it seemed clunky, so I decided to ajax it.  But, being a lazy programmer, I didn’t everything that WCF offers; I needed something simple and quick.  I remembered reading a couple of <a href="http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/" target="_blank">articles</a> about adding a static, “Webmethod” to a page.  So, that’s what I did.  In a previous post, I mentioned using Rick Strahl’s <a href="http://west-wind.com/WebLog/posts/762753.aspx" target="_blank">serviceproxy</a>, which makes the process as easy as can be.</p>
<p>So the details for implementing my web based tail applications goes like this:</p>
<ul>
<li>Create the ajax method as part of the web page.</li>
<li>Add <a href="http://codepaste.net/i89xhc" target="_blank">serviceproxy.js</a>, <a href="http://www.json.org/json2.js" target="_blank">json2.js</a> and <a href="http://codepaste.net/ojb76j" target="_blank">js_extensions.js</a> to enable ajax &amp; displaying the logs</li>
<li>Replace the text area with a standard div; more on this below…</li>
<li>Finally some handy, dandy css to make it look nicer.</li>
</ul>
<h4>Step 1 – The Webmethod</h4>
<div id="codeSnippetWrapper" style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:97.5%;height:300px;white-space:nowrap;overflow:auto;">
<div id="codeSnippet" style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;">
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum1" style="color:#606060;">   1:</span> [System.Web.Services.WebMethod]</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum2" style="color:#606060;">   2:</span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> IList&lt;<span style="color:#0000ff;">string</span>&gt; GetLogTail(<span style="color:#0000ff;">string</span> logname, <span style="color:#0000ff;">string</span> numrows)</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum3" style="color:#606060;">   3:</span> {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum4" style="color:#606060;">   4:</span>     <span style="color:#0000ff;">int</span> lineCnt = 1;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum5" style="color:#606060;">   5:</span>     List&lt;<span style="color:#0000ff;">string</span>&gt; lines = <span style="color:#0000ff;">new</span> List&lt;<span style="color:#0000ff;">string</span>&gt;();</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum6" style="color:#606060;">   6:</span>     <span style="color:#0000ff;">int</span> maxLines;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum7" style="color:#606060;">   7:</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum8" style="color:#606060;">   8:</span>     <span style="color:#0000ff;">if</span> (!<span style="color:#0000ff;">int</span>.TryParse(numrows, <span style="color:#0000ff;">out</span> maxLines))</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum9" style="color:#606060;">   9:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum10" style="color:#606060;">  10:</span>         maxLines = 100;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum11" style="color:#606060;">  11:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum12" style="color:#606060;">  12:</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum13" style="color:#606060;">  13:</span>     <span style="color:#0000ff;">string</span> logFile = HttpContext.Current.Server.MapPath(<span style="color:#006080;">"~/"</span> + logname);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum14" style="color:#606060;">  14:</span></pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum15" style="color:#606060;">  15:</span>     BackwardReader br = <span style="color:#0000ff;">new</span> BackwardReader(logFile);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum16" style="color:#606060;">  16:</span>     <span style="color:#0000ff;">while</span> (!br.SOF)</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum17" style="color:#606060;">  17:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum18" style="color:#606060;">  18:</span>         <span style="color:#0000ff;">string</span> line = br.Readline();</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum19" style="color:#606060;">  19:</span>         lines.Add(line + System.Environment.NewLine);</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum20" style="color:#606060;">  20:</span>         <span style="color:#0000ff;">if</span> (lineCnt == maxLines) <span style="color:#0000ff;">break</span>;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum21" style="color:#606060;">  21:</span>         lineCnt++;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum22" style="color:#606060;">  22:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum23" style="color:#606060;">  23:</span>     lines.Reverse();</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:#f4f4f4;width:100%;"><span id="lnum24" style="color:#606060;">  24:</span>     <span style="color:#0000ff;">return</span> lines;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:10pt;background-color:white;width:100%;"><span id="lnum25" style="color:#606060;">  25:</span> }</pre>
<p><!--CRLF--></p>
</div>
</div>
<p>It worked much better once I added “lines.Reverse()” before returning the data.  So the data returned is standard json, except there’s a “d” object that’s prepended to the data.  Rick’s serviceproxy handles this, so no worries.</p>
<h4>Step 2 – JavaScript</h4>
<p>serviceproxy.js and json2.js are used to deal with the asp.net peculiarities of ajax of asp.net.  See the links above; Rick’s site covers these in great detail.</p>
<p>js_extensions.js is my growing collection of javascript extension methods.  Currently, this is pretty small and contains other peoples work for formatting dates and HTML encoding and decoding.  My goal is to keep this small.</p>
<p>The heart of the whole thing is some jQuery that ties everything together, <a href="http://codepaste.net/msbmnb" target="_blank">here’s the code</a>.  Instead of going through all of the code, let’s just go over a few key points:</p>
<p>The heavy lifting is done in the getLogData method.</p>
<pre class="code"><span style="color:blue;">function </span>getLogData(numRows, logFile, isTail) {
    <span style="color:blue;">var </span>proxy = <span style="color:blue;">new </span>ServiceProxy(<span style="color:maroon;">"ViewLog.aspx/"</span>);
    proxy.isWcf = <span style="color:blue;">false</span>;
    proxy.invoke(<span style="color:maroon;">"GetLogTail"</span>, { logname: logFile, numrows: numRows },
        <span style="color:blue;">function </span>(data) {
            displayLog(logFile, data);
            <span style="color:blue;">if </span>(isTail) {
                <span style="color:blue;">var </span>method = <span style="color:maroon;">"getLogData(" </span>+ getNumRows() + <span style="color:maroon;">", '" </span>+ getLogFileName() + <span style="color:maroon;">"', "</span>+ isTail +<span style="color:maroon;">")"</span>;
                logTailId = setTimeout(method, getNumSecs());
            }
        },
        <span style="color:blue;">function </span>(errmsg) {
            clearTimeout(logTailId);
            alert(errmsg);
        },
        <span style="color:blue;">false</span>);        <span style="color:#006400;">// NOT bare
</span>}</pre>
<p>As you can see, there’s not much to it.  By setting “isWcf = false”  and passing in false for “bare” setting, the heaving lifting is done by the serviceproxy.  if successful, then display the data and call “setTimeout” for the next ajax call.  Okay, so I can hear you asking, “Why not use setInterval?”.  For 2 reasons, I decided to useSetTimeout: first, the precision isn’t important, and second, if the ajax method is slow, I don’t want to hammer the web set for log reading.  That’s all.</p>
<p>If there’s an error, clearTimeout is called, so we don’t keep calling the ajax method when things to bad.</p>
<p>displayLog is mostly</p>
<pre class="code"><span style="color:blue;">var </span>$log = $(<span style="color:maroon;">'#logDiv'</span>);
<span style="color:blue;">var </span>logStr = <span style="color:maroon;">""</span>;
<span style="color:blue;">for </span>(<span style="color:blue;">var </span>property <span style="color:blue;">in </span>data) {
    logStr += formatLine(data[property]);
}
$log.html(logStr);</pre>
<p>So, you probably would like to see the magic that is formatLine…</p>
<pre class="code"><span style="color:blue;">function </span>formatLine(line) {
    line = line.encodeHtml();
    <span style="color:blue;">if </span>(line.toLowerCase().indexOf(<span style="color:maroon;">'info'</span>) === 0) {
        <span style="color:blue;">return </span><span style="color:maroon;">"&lt;span class='info'&gt;" </span>+ line + <span style="color:maroon;">"&lt;/span&gt;&lt;br/&gt;"</span>;
    } <span style="color:blue;">else if </span>(line.toLowerCase().indexOf(<span style="color:maroon;">'error'</span>) === 0) {
        <span style="color:blue;">return </span><span style="color:maroon;">"&lt;span class='error'&gt;" </span>+ line + <span style="color:maroon;">"&lt;/span&gt;&lt;br/&gt;"</span>;
    } <span style="color:blue;">else if </span>(line.toLowerCase().indexOf(<span style="color:maroon;">'warn'</span>) === 0) {
        <span style="color:blue;">return </span><span style="color:maroon;">"&lt;span class='warn'&gt;" </span>+ line + <span style="color:maroon;">"&lt;/span&gt;&lt;br/&gt;"</span>;
    } <span style="color:blue;">else if </span>(line.toLowerCase().indexOf(<span style="color:maroon;">'debug'</span>) === 0) {
        <span style="color:blue;">return </span><span style="color:maroon;">"&lt;span class='debug'&gt;" </span>+ line + <span style="color:maroon;">"&lt;/span&gt;&lt;br/&gt;"</span>;
    }
    <span style="color:blue;">return </span><span style="color:maroon;">"&lt;span&gt;" </span>+ line + <span style="color:maroon;">"&lt;/span&gt;&lt;br/&gt;"</span>;
}</pre>
<p>The only interesting part of this is the “encodeHtml” method, which is one of the extension methods.</p>
<p>So when it is all done, this is how it looks.  To turn on the “tail” operation, click tail; that’s about it.<a href="http://kwiebke.files.wordpress.com/2010/12/log1.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="log1" src="http://kwiebke.files.wordpress.com/2010/12/log1_thumb.png?w=597&#038;h=178" border="0" alt="log1" width="597" height="178" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kwiebke.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kwiebke.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kwiebke.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kwiebke.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kwiebke.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kwiebke.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kwiebke.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kwiebke.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kwiebke.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kwiebke.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kwiebke.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kwiebke.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kwiebke.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kwiebke.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kwiebke.wordpress.com&amp;blog=5427164&amp;post=45&amp;subd=kwiebke&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kwiebke.wordpress.com/2010/12/19/website-log-tail/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/409fcb02215fdf7598b754bf9d8c5c3f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kwiebke</media:title>
		</media:content>

		<media:content url="http://kwiebke.files.wordpress.com/2010/12/log1_thumb.png" medium="image">
			<media:title type="html">log1</media:title>
		</media:content>
	</item>
	</channel>
</rss>
