<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2enclosuresfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>JAW Speak</title>
	
	<link>http://jawspeak.com</link>
	<description>Jonathan Andrew Wolter</description>
	<lastBuildDate>Wed, 24 Feb 2010 02:48:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/JAWspeak" /><feedburner:info uri="jawspeak" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>Jonathan Andrew Wolter</itunes:subtitle><feedburner:emailServiceId>JAWspeak</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>“No Project Was To Extend Beyond 90 Days”</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/46z0L0Ycfrc/</link>
		<comments>http://jawspeak.com/2010/02/23/no-project-was-to-extend-beyond-90-days/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 02:43:46 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[management consulting]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=193</guid>
		<description><![CDATA[Reading time: 2 &#8211; 4 minutes

			
				
			
		
McKinsey has an interview (pdf) with Kundapur Vaman Kamath, ICICI&#8217;s award winning MD and CEO from 1996 until 2009. He explains why he had no CIO, it was so strategic he brought it in as the CEO&#8217;s responsibilities. (An unusual move, considering the amount of effort two roles would stretch [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 2 &#8211; 4 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2010%2F02%2F23%2Fno-project-was-to-extend-beyond-90-days%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2010%2F02%2F23%2Fno-project-was-to-extend-beyond-90-days%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p><a href="http://www.mckinsey.com/clientservice/bto/home.asp"><img class="size-full wp-image-196   alignright" title="kvvkamath-ceo-cio" src="http://jawspeak.com/wp-content/uploads/2010/02/kvvkamath-ceo-cio.png" alt="PDF Link" width="148" height="194" />McKinsey</a> has an <a href="http://www.mckinsey.com/clientservice/bto/pointofview/pdf/MoIT11_ICICInterview_F.pdf">interview</a> (pdf) with <a href="http://en.wikipedia.org/wiki/K._V._Kamath">Kundapur Vaman Kamath</a>, ICICI&#8217;s <a href="http://www.rediff.com/money/2007/nov/29kamath.htm">award winning</a> MD and CEO from 1996 until 2009. He explains why he had no CIO, it was so strategic he brought it in as the CEO&#8217;s responsibilities. (An unusual move, considering the amount of effort two roles would stretch him very thin.) His boldness is evident in the following quote.</p>
<blockquote><p>[Startups] in Silicon Valley were taking products from concept to market in 90 days, because if they didn&#8217;t, somebody else would. So we asked, &#8220;Why can&#8217;t we?&#8221; <span style="background: #ffff99;">We made it a rule: no project was to extend beyond 90 days</span>. People were skeptical at first, but it was achievable, and it gave us a huge competitive edge. When I first heard about the 90-day rule at a seminar, we were building a platform for online brokerage almost from scratch. I got on the phone to Bombay from New York and said, &#8220;We need to get this done in 90 days.&#8221; The project had already been going for 30 days, so in the end I said, &#8220;OK, you can have 90 days from today.&#8221; The trading platform was up and running 90 days later. It cost us just over $1 million, and with some marginal tweaking&#8211;nothing more&#8211;it is still operating today.</p></blockquote>
<p>Imagine that! Every project must go to market in 90 days. What would your organization look like if you instituted such an aggressive policy?</p>
<p>If implemented in most organizations, I predict two outcomes:</p>
<ol>
<li>Many projects would be canceled, saving millions of dollars.</li>
<li>Surviving projects would release incrementally and progressively. No big up front design, followed by years of waterfall. Instead iterative enhancements and frequent production deployments. You won&#8217;t build what you don&#8217;t need, and you&#8217;ll get customer feedback faster to deliver more of what the customers want.</li>
</ol>
<p>His other quote was great as well:</p>
<blockquote><p>We decided to run technology in a radically different way from anyone else, so we don&#8217;t have a technology department or a glorious title like chief information officer. There is no CIO. Technology is embedded in every business, and the head of the business runs the technology.</p></blockquote>
<p>Closer business and technology interaction: a recipe for success.</p>
<p><small>ICICI is India&#8217;s largest private bank, who succeeds primarily because it can rapidly implement technologies giving it a competitive edge, says the bank&#8217;s chief executive, K. V. Kamath. Kamath, CEO of the Industrial Credit and Investment Corporation of India, considers information technology so central to the bank&#8217;s achievements that he manages it himself, without a CIO. Drawing inspiration from the culture and methodologies of Silicon Valley, Kamath has turned a stodgy industrial lender into a regional powerhouse with assets of $56 billion. Having learned to serve low-income consumers cost-effectively in India, ICICI now is exploring other markets.<br />
</small></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=46z0L0Ycfrc:WGutzJ1vvWQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/46z0L0Ycfrc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2010/02/23/no-project-was-to-extend-beyond-90-days/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<enclosure url="http://www.mckinsey.com/clientservice/bto/pointofview/pdf/MoIT11_ICICInterview_F.pdf" length="508061" type="application/pdf" /><media:content url="http://www.mckinsey.com/clientservice/bto/pointofview/pdf/MoIT11_ICICInterview_F.pdf" fileSize="508061" type="application/pdf" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>Reading time: 2 &amp;#8211; 4 minutes McKinsey has an interview (pdf) with Kundapur Vaman Kamath, ICICI&amp;#8217;s award winning MD and CEO from 1996 until 2009. He explains why he had no CIO, it was so strategic he brought it in as the CEO&amp;#8217;s responsibilit</itunes:subtitle><itunes:summary>Reading time: 2 &amp;#8211; 4 minutes McKinsey has an interview (pdf) with Kundapur Vaman Kamath, ICICI&amp;#8217;s award winning MD and CEO from 1996 until 2009. He explains why he had no CIO, it was so strategic he brought it in as the CEO&amp;#8217;s responsibilities. (An unusual move, considering the amount of effort two roles would stretch [...]</itunes:summary><itunes:keywords>management consulting</itunes:keywords><feedburner:origLink>http://jawspeak.com/2010/02/23/no-project-was-to-extend-beyond-90-days/</feedburner:origLink></item>
		<item>
		<title>Simplicity is Better for Deploying in Production Web Architectures</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/ojMaqeoOzA0/</link>
		<comments>http://jawspeak.com/2010/01/30/simplicity-is-better-for-deploying-in-production-web-architectures/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 18:20:49 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[architecture]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=180</guid>
		<description><![CDATA[Reading time: 5 &#8211; 8 minutes

			
				
			
		
Engineering something to be scalable, highly available, and easily manageable has been the focus of much of my time recently. Last time I talked about spiderweb architecture, because it has attributes of scalability and high availability, yet comes with a hidden cost. Complexity.
Here is a fictional set of questions, and [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 5 &#8211; 8 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2010%2F01%2F30%2Fsimplicity-is-better-for-deploying-in-production-web-architectures%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2010%2F01%2F30%2Fsimplicity-is-better-for-deploying-in-production-web-architectures%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>Engineering something to be scalable, highly available, and easily manageable has been the focus of much of my time recently. Last time I talked about <a title="Large Web App Architecture: Yes to Thicker Stack on One Hardware Node, No to Beautiful “Redundant” Spiderwebs" href="http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/">spiderweb architecture</a>, because it has attributes of scalability and high availability, yet comes with a hidden cost. Complexity.</p>
<p>Here is a fictional set of questions, and my responses for the application architecture.</p>
<p>Q: Why does complexity matter?<br />
JAW: Because when your system is complex, there is less certainty. Logical branches in the possible state of a system mean more work for engineers to create a mental model, and decide what action to take. Complexity means there are more points of unique failure.</p>
<p>Q: But my team is really, really smart; my engineers can handle clever and complex mental models!<br />
JAW: That wasn&#8217;t a question, but I do have a response.<span style="background: #ffff99;"> <em>Given a team at any moment in time, there is a finite amount of complexity that the team can deal with. Complexity can be in the application&#8217;s logic, dealing with delivering business value. Or, it can be in non functional requirements. If the NFR&#8217;s can be met with lower complexity, this will translate directly to more business value.</em></span> A team will grow in their ability to manage complexity as they understand more and more of it, and team size can increase. Although those productivity increases can be used for business value, or complex architectures. And often, NFR&#8217;s <a href="http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/">can be met</a> while still achieving simplicity.</p>
<p>Q: So how do I deal with a large, complex application which needs an emergency fix on one of the small components?<br />
JAW: Yes, I know the scenario. You want to make a small change into production, but it sounds less risky to only push one part. Here&#8217;s my recipe for success: <em>make every deployment identical, and automated</em>. (Ideally push into production from continuous builds, with automated testing.) In the event of an emergency push into production, alter the code from your version control tag, and deploy that as you would every other push. My colleague <a href="http://paulhammant.com/">Paul Hammant</a> call non-standard, risky pushes &#8220;white knuckle three-in-the-morning deployments.&#8221;</p>
<p>Don&#8217;t make the e-fix a one-off, non-standard production push. Have the entire system simple, and repeatable. <em>With repeatability and automated repetition comes security</em>. Very flexible (read: complex), extensible (read: rarely tested day to day) hooks can be built into a system, in order to make it <em>possible</em> to push just one small component into production. However in reality unused code becomes stale, and when a production emergency happens, people will be so scared to try these hooks. Or if they do, there is a greater risk of a misconfiguration, and failure. Which will necessitate a fix of the failed fix which tried to fix the original tiny defect. More complexity. Blowing the original availability requirements out of the water.</p>
<p>Q: So, what is simplicity?<br />
JAW: My definition says: <em>Simplicity</em> is the preference of fewer combinatorial states a system can be in. Choose defaults over</p>
<p>I recently read a quote from <a href="http://highscalability.com/youtube-architecture">High Scalability</a>, which I think gives a good definition of what simplicity is (emphasis added):</p>
<blockquote><p>&#8220;Keep it simple! Simplicity allows you to rearchitect more quickly so you can respond to problems. It&#8217;s true that nobody really knows what simplicity is, but <span style="background: #ffff99;"><em>if you aren&#8217;t afraid to make changes then that&#8217;s a good sign simplicity is happening.</em></span>&#8220;</p></blockquote>
<p>[Caveat: some complexity makes sense, it's just too much in the wrong places increases risk. And there is a threshold everyone needs to find: how much risk, how much flexibility, and how much energy to devote to reducing the risk while keeping high flexibility.]</p>
<p><strong>Update</strong>: Thanks to <a href="http://lucas-ward.blogspot.com/">Lucas</a>, for pointing me to an interesting article about <a href="http://arstechnica.com/business/data-centers/2010/02/what-second-life-can-teach-all-companies-about-scaling-web-apps.ars/2">second life scaling</a>:</p>
<blockquote><p>A preconditon of modern manufacturing, the concept of interchangeable parts that can help simplify the lower layers of an application stack, isn&#8217;t always embraced as a virtue. A common behavior of small teams on a tight budget is to tightly fit the building blocks of their system to the task at hand. It&#8217;s not uncommon to use different hardware configurations for the webservers, load balancers (more bandwidth), batch jobs (more memory), databases (more of everything), development machines (cheaper hardware), and so on. If more batch machines are suddenly needed, they&#8217;ll probably have to be purchased new, which takes time. Keeping lots of extra hardware on site for a large number of machine configurations becomes very expensive very quickly. This is fine for a small system with fixed needs, but the needs of a growing system will change unpredictably. When a system is changing, the more heavily interchangeable the parts are, the more quickly the team can respond to failures or new demands.</p>
<p>In the hardware example above, if the configurations had been standardized into two types (say Small and Large), then it would be possible to muster spare hardware and re-provision as demand evolved over time. This approach saves time and allows flexibility, and there are other advantages: standardized systems are easy to deploy in batches, because they do not need assigned roles ahead of time. They are easier to service and replace. Their strengths and weaknesses can be studied in detail.</p>
<p>All well and good for hardware, but in a hosted environment this sort of thing is abstracted away anyway, so it would seem to be a non-issue. Or is it? Again using the example above, replace &#8220;hardware&#8221; with &#8220;OS image&#8221; and many of the same issues arise: an environment where different components depend on different software stacks creates additional maintenance and deployment headaches and opportunities for error. The same could be said for programming languages, software libraries, network topologies, monitoring setups, and even access privileges.</p>
<p><span style="background: #ffff99;">The reason that interchangeable parts become a key scaling issue is that a complex, highly heterogeneous environment saps a team&#8217;s productivity</span> (and/or a system&#8217;s reliability) to an ever-greater degree as the system grows. (Especially if the team is also growing, and new developers are introducing new favorite tools.) The problems start small, and grow quietly. Therefore, a great long-term investment is to take a step back and ask, &#8220;what parts can we standardize? Where are there differences between systems which we can eliminate? Are the specialized outliers truly justified?&#8221; A growth environment is a good opportunity to standardize on a few components for future expansion, and gradually deprecate the exceptions.</p></blockquote>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=ojMaqeoOzA0:sSOAhVHVJL0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/ojMaqeoOzA0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2010/01/30/simplicity-is-better-for-deploying-in-production-web-architectures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jawspeak.com/2010/01/30/simplicity-is-better-for-deploying-in-production-web-architectures/</feedburner:origLink></item>
		<item>
		<title>Tips for Replacing a Broken iPhone 3G glass and touch sensor</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/nlVu40Kccag/</link>
		<comments>http://jawspeak.com/2010/01/02/tips-for-replacing-a-broken-iphone-3g-glass-and-touch-sensor/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 12:01:53 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=160</guid>
		<description><![CDATA[Reading time: 2 &#8211; 3 minutes

			
				
			
		

My glass screen broke by popping and spinning up outside of my jacket, landing glass-side-down on a bumpy pothole  a few weeks ago. It was right before going to China, so I didn&#8217;t have time to take it to an apple store. I covered the glass with a screen protector [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 2 &#8211; 3 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2010%2F01%2F02%2Ftips-for-replacing-a-broken-iphone-3g-glass-and-touch-sensor%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2010%2F01%2F02%2Ftips-for-replacing-a-broken-iphone-3g-glass-and-touch-sensor%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p><a title="IMG_1254 by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/4237642577/"><img class="alignright" src="http://farm3.static.flickr.com/2725/4237642577_8d4a12e799.jpg" alt="IMG_1254" width="168" height="126" /></a><br />
My glass screen broke by popping and spinning up outside of my jacket, landing glass-side-down on a bumpy pothole  a few weeks ago. It was right before going to China, so I didn&#8217;t have time to take it to an apple store. I covered the glass with a screen protector (to stop shards from falling off), and waited until I had more time. I even tried having a phone store in China look at repairing it, but my language barrier got in the way. They all kept trying to use styluses to touch the screen. Now that I&#8217;m back, I decided to repair it myself and here are my findings.</p>
<p>Order a replacement <a href="http://www.amazon.com/gp/product/B002A9PVAI">screen and touch sensor together</a>. Only my glass was broken, but they&#8217;re replaced as one unit.</p>
<p>First watch these <a href="http://www.youtube.com/watch?v=p3xn7whpZAA&amp;NR=1">two</a> helpful <a href="http://www.youtube.com/watch?v=dOPaCU96vV0">videos</a> for instructions. Make sure you remove the glass top with a suction cup (thanks Chris!), don&#8217;t pry it. Also, when removing the (unbroken in my case) LCD, do not pry on it. Instead pry on the metal frame it is attached to.</p>
<p><a title="IMG_1251 by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/4237640353/"><img class="alignright" src="http://farm3.static.flickr.com/2760/4237640353_236f98083a.jpg" alt="IMG_1251" width="168" height="126" /></a>Do not use too much heat when loosening the glue of the broken glass. This was my only mishap. I used a 2200 watt heat gun and warped and melted off a piece of the plastic frame. Then I spent an hour trying to reheat and bend it back. Also, watch out for repositioning the center button &#8211; mine went back in a millimeter lower on one side so it feels different. (Actually this is probably because of the warped frame.) Regarding the rubber gasket; be careful, but some damage may be unavoidable on it.</p>
<p>It took us about 2.5 hours to complete it, and I recovered from the heat gun mishap so that it&#8217;s not visible and everything fit back eventually. Plus it was fun to see the insides of the iPhone. Good luck!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=nlVu40Kccag:yYSn57aXHkk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/nlVu40Kccag" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2010/01/02/tips-for-replacing-a-broken-iphone-3g-glass-and-touch-sensor/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://jawspeak.com/2010/01/02/tips-for-replacing-a-broken-iphone-3g-glass-and-touch-sensor/</feedburner:origLink></item>
		<item>
		<title>maven + growlnotify for notification when your build finishes</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/abhgKYmaFrw/</link>
		<comments>http://jawspeak.com/2009/12/31/maven-growlnotify-for-notification-when-your-build-finishes/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 18:23:12 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[automation]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=154</guid>
		<description><![CDATA[Reading time: 1 &#8211; 2 minutes

			
				
			
		
Working on os x with Spaces means I want to read something on another space instead of waiting idly for a 50 second build. But, I don&#8217;t want to get distracted. So, I use Growl and growlnotify for notifications of the build&#8217;s completion.
#!/bin/sh
# this file is called: mvn (and is [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 1 &#8211; 2 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2009%2F12%2F31%2Fmaven-growlnotify-for-notification-when-your-build-finishes%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2009%2F12%2F31%2Fmaven-growlnotify-for-notification-when-your-build-finishes%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>Working on os x with Spaces means I want to read something on another space instead of waiting idly for a 50 second build. But, I don&#8217;t want to get distracted. So, I use <a href="http://growl.info/">Growl</a> and <a href="http://growl.info/documentation/growlnotify.php">growlnotify</a> for notifications of the build&#8217;s completion.</p>
<pre>#!/bin/sh
# this file is called: mvn (and is executable, and added to path before actual mvn command)

# capture all args passed in to forward to real mvn
ARGS=$*

# We need the client's specific settings.xml, so always specify it now
/usr/bin/mvn -s /Volumes/TrueCryptClient/opt/maven/conf/settings.xml $ARGS 

# when you have growlnotify installed and on your path, this will pop it up
# when the build is done
growlnotify -m "DONE: maven $ARGS"
</pre>
<p>Note: if you get this error from growlnotify: <tt>could not find local GrowlApplicationBridgePathway, falling back to NSDNC</tt>, it probably means growl is not started. Start up growl in your System Preferences.</p>
<p><strong>Update:</strong> Thanks Cosmin, for the enhancement. Use this snipped in the script. Have an environmental variable for what the notify command is. And say what the build status is in the growl notify.:</p>
<pre>if [[ -n $NOTIFY ]]; then
    ($command &amp;&amp; $NOTIFY "Build Complete" &amp;&amp; exit 0) || ($NOTIFY "Build Failed" &amp;&amp; exit 127)
else
    $command
fi
</pre>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=abhgKYmaFrw:cdARDj7dnPo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/abhgKYmaFrw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2009/12/31/maven-growlnotify-for-notification-when-your-build-finishes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jawspeak.com/2009/12/31/maven-growlnotify-for-notification-when-your-build-finishes/</feedburner:origLink></item>
		<item>
		<title>Can you spot Java Puzzler in this snippet?</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/Qar6b4S_lIM/</link>
		<comments>http://jawspeak.com/2009/09/30/can-you-spot-java-puzzler-in-this-snippet/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 19:51:17 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[puzzle]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=125</guid>
		<description><![CDATA[Reading time: 2 &#8211; 2 minutes

			
				
			
		
I ran across this last week. It was marvelous when we saw what was happening, but entirely puzzling at first.

Boolean someFlag = complicatedLogicToFigureOutFlag&#40;&#41;;
Person person = new Person&#40;someFlag&#41;;

Any signs for concern? How about if Person&#8217;s constructor is:

Person&#40;boolean someFlag&#41; &#123;
    this.someFlag = someFlag;
&#125;

Any warning signs?
Will it compile?
Read more for [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 2 &#8211; 2 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2009%2F09%2F30%2Fcan-you-spot-java-puzzler-in-this-snippet%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2009%2F09%2F30%2Fcan-you-spot-java-puzzler-in-this-snippet%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>I ran across this last week. It was marvelous when we saw what was happening, but entirely puzzling at first.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">Boolean</span> someFlag <span style="color: #339933;">=</span> complicatedLogicToFigureOutFlag<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Person person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span>someFlag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Any signs for concern? How about if Person&#8217;s constructor is:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Person<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">boolean</span> someFlag<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">someFlag</span> <span style="color: #339933;">=</span> someFlag<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Any warning signs?</p>
<p>Will it compile?</p>
<p>Read more for the full puzzler.</p>
<p><span id="more-125"></span></p>
<p>If you didn&#8217;t see a warning sign, but said it would compile &#8212; you&#8217;re half right. It will compile, but there&#8217;s a great big NullPointer waiting for you depending on the value of someFlag. Because autoboxing was a shim initially slid into Java 1.5, this will compile:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">Boolean</span> someFlag <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
Person person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span>someFlag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// will compile, but then NPE ambiguously</span></pre></div></div>

<p>But at runtime, it will fail ambiguously with a Null Pointer on the line of the constructor.</p>
<p>Of course, this will not compile:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Person person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// won't compile because signature is boolean</span></pre></div></div>

<p>My pair and I saw this in a test with a particularly ugly constructor with 12 parameters. We were following <a href="http://misko.hevery.com/2009/02/09/to-assert-or-not-to-assert/">Misko</a>&#8217;s style of &#8220;use nulls in tests, but not in production code&#8221; and thus that Boolean was ending up as null. By binary search we identified which parameter caused the trouble, initialized it to false instead of null, and then shared our &#8220;Ah Ha!&#8221; moment with several other engineers around the office.</p>
<p>Should something like this be an interview question you ask a candidate? Maybe if they are doing great on all other fronts, and you&#8217;re curious how well they understand the intricacies of Java. But I don&#8217;t generally like obscure fact questions because in real life we just figure them out. So, yes I would use this in an interview where we are pairing, so I could watch the candidate troubleshoot.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=Qar6b4S_lIM:fSTbNRW99ZA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/Qar6b4S_lIM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2009/09/30/can-you-spot-java-puzzler-in-this-snippet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jawspeak.com/2009/09/30/can-you-spot-java-puzzler-in-this-snippet/</feedburner:origLink></item>
		<item>
		<title>How to do 3-way merges with Subversion and Kdiff3</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/9aC_VUlLPU8/</link>
		<comments>http://jawspeak.com/2009/09/17/how-to-do-3-way-merges-with-subversion-and-kdiff3/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 01:49:37 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[automation]]></category>
		<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=140</guid>
		<description><![CDATA[Reading time: 4 &#8211; 7 minutes

			
				
			
		
I do not endorse branch based development. I prefer trunk based development. Specifically I like what my colleague Paul calls Branch By Abstraction, coined by Stacy Curl, and recently mentioned by Martin Fowler (All one time ThoughtWorkers, and 2 currently).
If you&#8217;re stuck with merging though, 3-way merges make it much [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 4 &#8211; 7 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2009%2F09%2F17%2Fhow-to-do-3-way-merges-with-subversion-and-kdiff3%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2009%2F09%2F17%2Fhow-to-do-3-way-merges-with-subversion-and-kdiff3%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>I do not endorse branch based development. I prefer trunk based development. Specifically I like what my colleague Paul calls <a href="http://paulhammant.com/blog/branch_by_abstraction.html">Branch By Abstraction</a>, coined by <a href="http://digital-compulsion.blogspot.com/2007/04/branching-by-abstraction.html">Stacy Curl</a>, and recently mentioned by <a href="http://martinfowler.com/bliki/FeatureBranch.html">Martin Fowler</a> (All one time <a href="http://ThoughtWorks.com">ThoughtWorkers</a>, and 2 currently).</p>
<p>If you&#8217;re stuck with merging though, 3-way merges make it much easier. Doing it with subversion is easy. Instructions are for Linux.</p>
<ol>
<li>apt-get or yum install kdiff3.</li>
<li>Edit your <tt>/etc/subversion/config</tt> and fin the line with <tt>diff3-cmd</tt>, set it to: <tt>diff3-cmd=/usr/local/bin/svndiff.sh</tt></li>
<li>Next, create the file <tt>/usr/local/bin/svndiff.sh</tt>. See below for the script you&#8217;ll want to enter in it.</li>
</ol>
<p>Now when you get a merge conflict you will choose <tt>M</tt> and merge will open in kdiff3. On the left is the base revision, in the middle is your working copy, and on the right the incoming change. This is a little more to look at, but it is invaluable when dealing with merges. I wouldn&#8217;t go back to 2 way diff ever again.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">#!/bin/bash
&nbsp;
# NOTE: I DO NOT SUPPORT BRANCH BASED DEVELOPMENT, but sometimes you're stuck with it.
&nbsp;
# tim/paul: this is a copy of the file located at &lt;a href=&quot;http://www.yolinux.com/TUTORIALS/src/svndiffwrapper.txt&quot;&gt;http://www.yolinux.com/TUTORIALS/src/svndiffwrapper.txt&lt;/a&gt;
&nbsp;
# modified to do a non-conflicting merge automatically. see #HERE#
# INSTALLATION:
# 1) Place this file in /usr/local/bin
# 2) Add to /etc/subversion/config a line: diff3-cmd=/usr/local/bin/svndiff.sh
# Then, svn should use this script, which will use kdiff3 to do three way merging.
&nbsp;
# Return an errorcode of 0 on successful merge, 1 if unresolved conflicts
# remain in the result. Any other errorcode will be treated as fatal.
# Author: Michael Bradley
&nbsp;
#NOTE: all output must be redirected to stderr with &quot;1&amp;gt;&amp;amp;2&quot; as all stdout output is written to the output file
&nbsp;
VDIFF3=&quot;kdiff3&quot;
DIFF3=&quot;diff3&quot;
DIFF=&quot;kdiff3&quot;
&nbsp;
promptUser ()
{
    read answer
    case &quot;${answer}&quot; in
&nbsp;
        &quot;M&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Attempting to merge ${baseFileName} with ${DIFF}&quot; 1&amp;gt;&amp;amp;2
        $VDIFF3 $older $mine $theirs  L1 $labelOlder  L2 $labelMine  L3 $labelTheirs -o $output 1&amp;gt;&amp;amp;2
        bLoop=1
        if [ -f $output ]; then
if [ -s $output ]; then
                #output succesfully written
                bLoop=0
            fi
fi
if [ $bLoop = 0 ]; then
cat $output
            rm -f $output
            exit 0
        else
echo &quot;Merge failed, try again&quot; 1&amp;gt;&amp;amp;2
        fi
&nbsp;
        ;;
&nbsp;
        &quot;m&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Attempting to auto-merge ${baseFileName}&quot; 1&amp;gt;&amp;amp;2
        diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $older $theirs &amp;gt; $output
        if [ $? = 1 ]; then
            #Can't auto merge
            rm -f $output
            $VDIFF3 $older $mine $theirs  L1 $labelOlder  L2 $labelMine  L3 $labelTheirs -o $output  auto 1&amp;gt;&amp;amp;2
            bLoop=1
            if [ -f $output ]; then
if [ -s $output ]; then
                    #output succesfully written
                    bLoop=0
                fi
fi
if [ $bLoop = 0 ]; then
cat $output
                rm -f $output
                exit 0
            else
echo &quot;Merge failed, try again&quot; 1&amp;gt;&amp;amp;2
            fi
else
            #We can automerge, and we already did it
            cat $output
            rm -f $output
            exit 0
        fi
        ;;
&nbsp;
        &quot;diff3&quot; | &quot;Diff3&quot; | &quot;DIFF3&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Diffing...&quot; 1&amp;gt;&amp;amp;2
        $VDIFF3 $older $mine $theirs  L1 $labelOlder  L2 $labelMine  L3 $labelTheirs 1&amp;gt;&amp;amp;2
        ;;
&nbsp;
        &quot;diff&quot; | &quot;Diff&quot; | &quot;DIFF&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Diffing...&quot; 1&amp;gt;&amp;amp;2
        $DIFF $mine $theirs -L $labelMine -L $labelTheirs 1&amp;gt;&amp;amp;2
        ;;
&nbsp;
        &quot;A&quot; | &quot;a&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Accepting remote version of file...&quot; 1&amp;gt;&amp;amp;2
        cat ${theirs}
        exit 0
        ;;
&nbsp;
        &quot;I&quot; | &quot;i&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Keeping local modifications...&quot; 1&amp;gt;&amp;amp;2
        cat ${mine}
        exit 0
        ;;
&nbsp;
        &quot;R&quot; | &quot;r&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Reverting to base...&quot; 1&amp;gt;&amp;amp;2
        cat ${older}
        exit 0
        ;;
&nbsp;
        &quot;D&quot; | &quot;d&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Runnig diff3...&quot; 1&amp;gt;&amp;amp;2
        diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $older $theirs
        #Exit with return vaule of the diff3 (to write out files if necessary)
        exit $?
        ;;
&nbsp;
        &quot;S&quot; | &quot;s&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Saving for later...&quot; 1&amp;gt;&amp;amp;2
        cat ${mine}
        #Exit with return vaule of 1 to force writting of files
        exit 1
        ;;
&nbsp;
        &quot;Fail&quot; | &quot;fail&quot; | &quot;FAIL&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;Failing...&quot; 1&amp;gt;&amp;amp;2
        exit 2
        ;;
&nbsp;
        &quot;H&quot; | &quot;h&quot; )
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        echo &quot;USAGE OPTIONS:&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [A]ccept Accept $labelTheirs and throw out local modifications&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [D]efault Use diff3 to merge files (same behavior as vanilla SVN)&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [Fail] Kills the command (not suggested)&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [H]elp Print this message&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [I]gnore Keep your locally modified version as is&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [M]erge Manually merge using ${VDIFF3}&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [m]erge Same as &quot;M&quot; but attempts to automerge if possible&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [R]evert Revert to base version (${labelOlder})&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [S]ave Same as 'I' but writes out rold, rnew, and rmine files to deal with later&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [diff] Type 'diff' to diff versions $labelMine and $labelTheirsthe before making a descision&quot; 1&amp;gt;&amp;amp;2
        echo &quot; [diff3] Type 'diff3' to diff all three versions before making a descision&quot; 1&amp;gt;&amp;amp;2
        echo &quot;&quot; 1&amp;gt;&amp;amp;2
        ;;
&nbsp;
        * )
        echo &quot;'${answer}' is not an option, try again.&quot; 1&amp;gt;&amp;amp;2
        ;;
    esac
}
&nbsp;
if [ -z $2 ]
then
echo ERROR: This script expects to be called by subversion
    exit 1
fi
&nbsp;
if [ $2 = &quot;-m&quot; ]
then
    #Setup vars
    labelMine=${4}
    labelOlder=${6}
    labelTheirs=${8}
    mine=${9}
    older=${10}
    theirs=${11}
    output=${9}.svnDiff3TempOutput
    baseFileName=`echo $mine | sed -e &quot;s/.tmp$//&quot;`
&nbsp;
#HERE#
    diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $older $theirs &amp;gt; $output
    if [ $? = 1 ]; then
        #Can't auto merge
        #Prompt user for direction
        while [ 1 ]
        do
echo &quot;&quot; 1&amp;gt;&amp;amp;2
            echo &quot;${baseFileName} requires merging.&quot; 1&amp;gt;&amp;amp;2
            echo &quot;&quot; 1&amp;gt;&amp;amp;2
            echo &quot;What would you like to do?&quot; 1&amp;gt;&amp;amp;2
            echo &quot;[M]erge [A]ccept [I]gnore [R]evert [D]efault [H]elp&quot; 1&amp;gt;&amp;amp;2
            promptUser
        done
else
        #We can automerge, and we already did it
        cat $output
        rm -f $output
        exit 0
    fi
else
L=&quot;-L&quot; #Argument option for left label
    R=&quot;-L&quot; #Argument option for right label
    label1=$3 #Left label
    label2=$5 #Right label
    file1=$6 #Left file
    file2=$7 #Right file
&nbsp;
    $DIFF $file1 $file2 $L &quot;$label1&quot; $L &quot;$label2&quot; &amp;amp;
    #$DIFF $file1 $file2 &amp;amp;
    #wait for the command to finish
    wait
fi
exit 0</pre></div></div>

<p>Note: I also posted this to a gist on github: <a href="http://gist.github.com/188824">svndiff.sh</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=9aC_VUlLPU8:WaSv4iV2KII:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/9aC_VUlLPU8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2009/09/17/how-to-do-3-way-merges-with-subversion-and-kdiff3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jawspeak.com/2009/09/17/how-to-do-3-way-merges-with-subversion-and-kdiff3/</feedburner:origLink></item>
		<item>
		<title>Ruby Script to Organize Mp3’s based on ID3 Genre Tag</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/kPqB--Ncxdg/</link>
		<comments>http://jawspeak.com/2009/09/05/ruby-script-to-organize-mp3s-based-on-id3-genre-tag/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 00:06:57 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[automation]]></category>
		<category><![CDATA[music]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=136</guid>
		<description><![CDATA[Reading time: 2 &#8211; 4 minutes

			
				
			
		
I had one gigantic directory of all my tagged and organized mp3 files. Problem is it was too big to use. This bloated my library and I have since not been able to fit my music on my laptop. I needed to manipulate mp3 files by genre and extract them [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 2 &#8211; 4 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2009%2F09%2F05%2Fruby-script-to-organize-mp3s-based-on-id3-genre-tag%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2009%2F09%2F05%2Fruby-script-to-organize-mp3s-based-on-id3-genre-tag%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>I had one gigantic directory of all my tagged and organized mp3 files. Problem is it was too big to use. This bloated my library and I have since not been able to fit my music on my laptop. I needed to manipulate mp3 files by genre and extract them out of this single directory to create smaller libraries. I spent all of about two minutes looking for a program to do this before deciding to write a script. Truthfully, it was worse: once upon a time I over-enthusiastically downloaded <a href="http://www.stepmania.com/">StepMania</a> and 493 DDR games/songs. And then, I added all the songs into my music library. It&#8217;s a great party game, but not the kind of music I want to listen to.</p>
<p>Many <a href="http://www.id3.org/Implementations">implementations</a> exist for reading <a href="http://en.wikipedia.org/wiki/ID3">ID3</a> tags. I first tried <a href="http://ruby-mp3info.rubyforge.org/">ruby-mp3info</a>, however it didn&#8217;t read my custom genre (&#8216;DDR&#8217;) so then I moved to <a href="http://id3lib-ruby.rubyforge.org/">id3lib-ruby</a> which uses the c++ <a href="http://id3lib.sourceforge.net/">id3lib</a> library.</p>
<p>This worked like a charm. I ran the script over all my directories and built up a list of the directories.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
<span style="color:#008000; font-style:italic;"># find_music.sh</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;rubygems&quot;</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'id3lib'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'find'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'set'</span>
&nbsp;
ddr_files = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
ddr_dirs = <span style="color:#CC00FF; font-weight:bold;">Set</span>.<span style="color:#9900CC;">new</span>
&nbsp;
search_dir = <span style="color:#996600;">'~/media/music/music_categorized'</span>
&nbsp;
<span style="color:#CC00FF; font-weight:bold;">Find</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>search_dir<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>file<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#9966CC; font-weight:bold;">next</span> <span style="color:#9966CC; font-weight:bold;">if</span> file !~ <span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#006600; font-weight:bold;">*</span>mp3$<span style="color:#006600; font-weight:bold;">/</span>
  mp3 = <span style="color:#6666ff; font-weight:bold;">ID3Lib::Tag</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>file<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">next</span> <span style="color:#9966CC; font-weight:bold;">if</span> mp3.<span style="color:#9900CC;">genre</span> != <span style="color:#996600;">'DDR'</span>
  ddr_dirs <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span>file<span style="color:#006600; font-weight:bold;">&#41;</span>
  ddr_files <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> file   <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;%s, %s --&gt; AT: %s&quot;</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#006600; font-weight:bold;">&#91;</span>mp3.<span style="color:#9900CC;">genre</span>, mp3.<span style="color:#9900CC;">album</span>, file<span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'result-ddr-files.txt'</span>, <span style="color:#996600;">'w'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
  f.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>ddr_files.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;<span style="color:#000099;">\n</span>&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'result-ddr-dirs.txt'</span>, <span style="color:#996600;">'w'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
  ddr_dirs.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>d<span style="color:#006600; font-weight:bold;">|</span> f.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;%s<span style="color:#000099;">\n</span>&quot;</span> <span style="color:#006600; font-weight:bold;">%</span> d<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Next I reviewed the two output files, then ran the file <tt>result-ddr-dirs.txt</tt> in as an argument into this next script. That removed almost a gig of music from my library.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>ARGV.<span style="color:#9900CC;">length</span> != <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Usage: #{__FILE__} input_file&quot;</span>
  <span style="color:#CC0066; font-weight:bold;">exit</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
destination=<span style="color:#996600;">&quot;/home/jwolter/media/music/music_ddr_questionable_value/&quot;</span>
&nbsp;
<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">foreach</span><span style="color:#006600; font-weight:bold;">&#40;</span>ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>line<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#9966CC; font-weight:bold;">next</span> <span style="color:#9966CC; font-weight:bold;">if</span> line.<span style="color:#9900CC;">strip</span> == <span style="color:#996600;">&quot;&quot;</span>
  cmd =  <span style="color:#996600;">&quot;mv <span style="color:#000099;">\&quot;</span>#{line.strip}<span style="color:#000099;">\&quot;</span> <span style="color:#000099;">\&quot;</span>#{destination}<span style="color:#000099;">\&quot;</span>&quot;</span>
  <span style="color:#008000; font-style:italic;">#puts cmd</span>
  <span style="color:#996600;">`#{cmd}`</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Bonus: In the process searching for this, I ran into the <a href="http://rubyquiz.com/quiz136.html">ID3 Tags RubyQuiz</a>.</p>
<p>One of the nicest benefits of being a software engineer is I avoid doing boring manual tasks on my computer. Writing a script is more fun, and faster. I&#8217;ve got many scripts to automate file manipulation, online banking, and more. What bit of your automation scripts do you think is the most helpful?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=kPqB--Ncxdg:rzqrcHyPrMo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/kPqB--Ncxdg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2009/09/05/ruby-script-to-organize-mp3s-based-on-id3-genre-tag/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jawspeak.com/2009/09/05/ruby-script-to-organize-mp3s-based-on-id3-genre-tag/</feedburner:origLink></item>
		<item>
		<title>Movie Review: Bigger Stronger Faster. I ask how far to go for better performance?</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/DgChe4la_j0/</link>
		<comments>http://jawspeak.com/2009/08/30/movie-review-bigger-stronger-faster/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 09:25:17 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[Movie Reviews]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=120</guid>
		<description><![CDATA[Reading time: 5 &#8211; 8 minutes

			
				
			
		
Watching a movie that entertains is fun, one that teaches benefits you tomorrow, and ones that make you think in a new way are the best of all. I have a friend who says periodically it&#8217;s time to go to a conference, &#8220;in order to introduce randomness into the system.&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 5 &#8211; 8 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2009%2F08%2F30%2Fmovie-review-bigger-stronger-faster%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2009%2F08%2F30%2Fmovie-review-bigger-stronger-faster%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>Watching a movie that entertains is fun, one that teaches benefits you tomorrow, and ones that make you think in a new way are the best of all. I have a friend who says periodically it&#8217;s time to go to a conference, &#8220;in order to introduce randomness into the system.&#8221; Shake things up. Movies in &#8220;Cerebral&#8221; category in Netflix are a new way I found to do this. My hope is for comments and further recommendations of thought-worthy movies.<em> </em></p>
<p><em><a href="http://www.imdb.com/title/tt1151309/"><em>Bigger Stronger Faster</em></a> is a documentary. <img class="alignright size-full wp-image-121" title="bigger stronger faster" src="http://jawspeak.com/wp-content/uploads/2009/08/bigger-stronger-faster.jpg" alt="bigger stronger faster" width="100" height="139" /></em>Technically it&#8217;s about steroids in American culture, but it also raises the clear lack of consistency we treat <em>other performance enhancers</em>. The director Christopher Bell examines his brothers as they use steroids.</p>
<p><strong>What is an ethical and responsible limit to how far you are willing to go for success?</strong> Is it okay to wake up in the morning and say you are destined for greatness &#8211; that somehow you were born to give something to the world? (And how far will you then go?) Is it okay to just become a normal, average, person?</p>
<ul>
<li>When Tiger Woods had laser eye correction to 20/15 vision, was that an unethical performance enhancement?</li>
<li>How about professional musicians taking beta blockers to eliminate anxiety before performances and auditions?</li>
<li>Athletes&#8217; are dependent on cortisone shots (a legal steroid), yet should those be held equal to anabolic steroids?</li>
<li>Red blood cell count can be increased by doping, taking EPO (<a title="Wikipedia on Doping and EPO" href="http://en.wikipedia.org/wiki/Use_of_performance-enhancing_drugs_in_sport">details</a>), high altitude training, or sleeping in an altitude chamber. Two options are illegal, two are legal. Should the end result (higher than natural RBC&#8217;s) be the determiner of ethics, rather than the mechanism used to reach it?</li>
<li>The US Air Force gives fighter pilots <a href="http://en.wikipedia.org/wiki/Amphetamine">speed (amphetamine)</a> to perform better, is that a rational decision?</li>
<li>He interviews a member of the Olympic Doping Committee and is told that routinely US Athletes are flagged for failing drug tests, but still allowed to compete.</li>
<li>Attending a Chiropractor Anti-aging specialist Chris is able to say he suspects a hormone deficiency which leads to tests and results where no &#8220;healthy&#8221; range has been set enables him to get an <a href="http://en.wikipedia.org/wiki/Growth_hormone">Human Growth Hormone</a> prescription &#8211; legally.</li>
<li>Students are interviewed in how easy it is to get <a href="http://en.wikipedia.org/wiki/Adderall">Adderoll</a> (just tell your doctor you have trouble focusing, or have it passed around from friends). Are these and other <a href="http://en.wikipedia.org/wiki/Nootropic">&#8220;study drugs&#8221;</a> (long but really interesting article) worth it? (<em>Or, should everyone be taking them?</em>)</li>
</ul>
<p>I&#8217;m not ready to jump on the film&#8217;s open skepticism of &#8220;are steroids actually a health risk?&#8221; I don&#8217;t think they are naturally necessary and a cautious approach to my health comes intuitively. They cross my line of fair competition. Throughout sports and recreational fitness I was never tempted to try them. <em>But maybe that was just because I wasn&#8217;t/didn&#8217;t want to become good enough to compete at the highest level?<br />
</em></p>
<p><strong>But how far will we go for performance outside of sports?</strong> If you could close 70% more sales by taking &#8220;Synthesized Aquatic Maltose&#8221; (which I just invented), would you take it? Health Supplements in the US are not regulated to be proven healthy, the FDA has the job of proving them unhealthy.</p>
<blockquote><p>Under the Dietary Supplement Health and Education Act of 1994 (DSHEA), the dietary supplement manufacturer is responsible for ensuring that a dietary supplement is safe before it is marketed. FDA is responsible for taking action against any unsafe dietary supplement product after it reaches the market. <em>Generally, manufacturers do not need to register their products with FDA nor get FDA approval before producing or selling dietary supplements.</em> &#8212; <a href="http://www.fda.gov/Food/DietarySupplements/default.htm">FDA on DSHEA</a></p></blockquote>
<p>Therefore I could start selling this new supplement and require no doctors or nutritionists to even look at what my customers would start to ingest. Chris actually does this. Entertainingly, he picks up a few illegal day laborers, and invents a product and fills pills with his &#8220;proprietary blend&#8221; of powders. He does &#8220;before/after&#8221; pictures the same day at a photo shoot and can start selling this $40/bottle tonic. (Of course, manufacturing cost are under $5/bottle for him).</p>
<p>There is more, such as how Utah&#8217;s third largest economy ($2.5-$4 billion/year) is the health supplement industry (<a href="http://www.deseretnews.com/article/print/600135508/Healthy-business-Snake-oil-or-cure-all-Nutrition-supplements-are-booming-in-Utah.html">Nice article here about Utah&#8217;s supplement industry</a>). Legislation from Utah&#8217;s Senator <a href="http://en.wikipedia.org/wiki/Orrin_Hatch">Orrin Hatch</a> made for the passing of DSHEA, and continues to enable those too squeamish for &#8220;real steroids&#8221; to get something that promises the same benefits.</p>
<p>He goes on to show a breed of cow: Belgium Blue. Through 100 years of natural selection, these cows are deficient in Myostatin, a growth factor that limits muscle growth. Video below gives a peek. Researchers are looking to mimic that for fighting Muscular Distrophy in humans. See more freakish links about this <a href="http://www.chinadaily.com.cn/english/doc/2004-06/25/content_342496.htm">gene mutation in humans</a>, <a href="http://www.hemmy.net/2007/07/16/belgian-blue-cattle-super-cow-aka-incredible-hulk-cow/">cows</a>, or <a href="http://www.who-sucks.com/people/monstrous-myostatin-misfortunes-a-collection-of-myostatin-deficiency-pictures">other animals</a>. Note: Clip below from National Geographic, not from the movie.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/Nmkj5gq1cQU&amp;hl=en&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/Nmkj5gq1cQU&amp;hl=en&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Chris goes to say that Americans are all about Bigger Stronger Faster, and it&#8217;s un-American to be #2. We even have romanticized the concept, calling things bigger than expected as &#8220;Xyz, on steroids.&#8221; We must win, and we must win better than we previously won.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=DgChe4la_j0:_-JriirvLc4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/DgChe4la_j0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2009/08/30/movie-review-bigger-stronger-faster/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<enclosure url="http://www.youtube.com/v/Nmkj5gq1cQU&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" length="1019" type="application/x-shockwave-flash" /><media:content url="http://www.youtube.com/v/Nmkj5gq1cQU&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" fileSize="1019" type="application/x-shockwave-flash" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>Reading time: 5 &amp;#8211; 8 minutes Watching a movie that entertains is fun, one that teaches benefits you tomorrow, and ones that make you think in a new way are the best of all. I have a friend who says periodically it&amp;#8217;s time to go to a conference, </itunes:subtitle><itunes:summary>Reading time: 5 &amp;#8211; 8 minutes Watching a movie that entertains is fun, one that teaches benefits you tomorrow, and ones that make you think in a new way are the best of all. I have a friend who says periodically it&amp;#8217;s time to go to a conference, &amp;#8220;in order to introduce randomness into the system.&amp;#8221; [...]</itunes:summary><itunes:keywords>Movie Reviews</itunes:keywords><feedburner:origLink>http://jawspeak.com/2009/08/30/movie-review-bigger-stronger-faster/</feedburner:origLink></item>
		<item>
		<title>Large Web App Architecture: Yes to Thicker Stack on One Hardware Node, No to Beautiful “Redundant” Spiderwebs</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/syNaBLr_z5c/</link>
		<comments>http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 05:55:21 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=118</guid>
		<description><![CDATA[Reading time: 4 &#8211; 7 minutes

			
				
			
		
My last client our team worked with had a large ecommerce operation. Yearly revenue in the new site is in the high single digit billions of dollars. This necessitates extremely high availability. I will draw an initially favorable looking configuration for this high availability (&#8220;beautiful spiderwebs&#8221;), but then tear it [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 4 &#8211; 7 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2009%2F08%2F19%2Flarge-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2009%2F08%2F19%2Flarge-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>My last client our team worked with had a large ecommerce operation. Yearly revenue in the new site is in the high single digit billions of dollars. This necessitates extremely high availability. I will draw an initially favorable looking configuration for this high availability (&#8220;beautiful spiderwebs&#8221;), but then tear it apart and suggest an alternative (&#8220;Thicker Stack on One Hardware&#8221;).</p>
<h3>1. &#8220;Beautiful Spiderwebs&#8221; &#8211; Often Not Recommended</h3>
<p>Here&#8217;s one common way people could implement high availability. Notice how there are always multiple routes available for servicing a request. If one BIG IP goes down, there is another to help. And this could be doubled with multiple data centers, failed over with DNS.</p>
<p>The visible redundancy and complexity in one diagram may be appealing. One can run through scenarios in order to make sure that yes, we can actually survive any failure and the ecommerce will not stop.</p>
<p><a title="not recommended spiderweb tiers by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/3836184306/"><img src="http://farm3.static.flickr.com/2588/3836184306_96e6a18f29.jpg" alt="not recommended spiderweb tiers" width="443" height="500" /></a></p>
<p>So then what could make this my <em>Not Recommended </em>option?<em><br />
</em></p>
<h3>2. Martin&#8217;s Reminder how to Think About Nodes</h3>
<p>Fowler reminded us in <a href="http://www.amazon.com/gp/product/0321127420?ie=UTF8&amp;tag=econtechblog-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0321127420">Patterns of Enterprise Application Architecture</a> how to look at distribution and tiers. For some reason people keep wanting to have certain &#8220;machines running certain services&#8221; and <em>just</em> make a <em>few</em> service calls to stitch up all the services you need. If you&#8217;re concerned about performance, though, you&#8217;re a looking for punishment. Remote calls are several orders of magnitude greater than in process, or calls within the same machine. And this architectural preference is rarely necessary.</p>
<p>One might lead to the first design with the logic of: &#8220;We can run each component on a separate box. If one component gets too busy we add extra boxes for it so we can load-balance our app.&#8221; Is that a good idea?</p>
<p><a title="fowler distributed objects not recommended by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/3835392251/"><img src="http://farm3.static.flickr.com/2551/3835392251_d4824c236f.jpg" alt="fowler distributed objects not recommended" width="500" height="299" /></a></p>
<p>The above is not recommended:</p>
<blockquote><p>A procedure call between two separate processes is orders of magnitude slower [than in-process]. Make that a process running on another machine and you can add another order of magnitude or two, depending on the network topography involved. [PoEAA Ch 7]</p></blockquote>
<p>This leads into his <em>First Law of Distributed Object Design: Don&#8217;t distribute your objects!</em></p>
<p>The solution?</p>
<blockquote><p>Put all the classes into a single process and then run multiple copies of that process on the various nodes. That way each process uses local calls to get the job done and thus does things faster. You can also use fine- grained interfaces for all the classes within the process and thus get better maintainability with a simpler programming model. [PoEAA Ch 7]</p></blockquote>
<p><a title="fowler clustered application recommended by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/3835392281/"><img src="http://farm4.static.flickr.com/3580/3835392281_35920eff8d.jpg" alt="fowler clustered application recommended" width="463" height="307" /></a></p>
<h3>3. &#8220;Strive for Thicker Stack on One Hardware Node&#8221; &#8211; Recommended</h3>
<p>Observe the recommended approach below. There is still an external load balancer, but after a request is routed to an Apache/Nginx/etc front end, you&#8217;re all on one* machine.</p>
<p>If one tier fails on a node, pull the whole node out from rotation. Replace it. And re-enter it in the mix.</p>
<p>Your companies teams have worked together to be able to deploy modular services. So when your ecommerce site needs a merchant gateway processing service, you can include that (library or binary) and run it locally on your node, making a call through to it as needed.</p>
<p>Services are also simpler to deploy, upgrade and monitor as there are fewer processes and fewer differently-configured machines.</p>
<p><a title="recommended thicker nodes tiers by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/3835392219/"><img src="http://farm3.static.flickr.com/2525/3835392219_88ca43602b.jpg" alt="recommended thicker nodes tiers" width="500" height="429" /></a></p>
<p>(* I understand there may be the occasional exception for remote calls that need to be made to other machines. Possibly databases, mcached obviously third party hosted services, but the point is <em>most everything else</em> need not be remote.)</p>
<h3>4. But, Practically Speaking How Far Do We Go?</h3>
<p>A caveat first: these benefits get pronounced as you have more and more nodes. (And thus, more and more complex of spiderwebs of unnecessary failover).</p>
<p>Should there be a database server running on each node? Probably not at first. There is a maintenance associated with that. But after sharding your database and running with replication, why not? This way if a node fails, you simply pull it out and replace it with a functioning one.</p>
<h3>5. Checklist of Takeaway Lessons</h3>
<ol>
<li>Keep it local. Local calls orders of magnitude faster than remote calls.</li>
<li>Make services modular so they don&#8217;t need to be remote, yet still have all the organizational benefits of separate teams.</li>
<li>Simplicity in node-level-redundancy is preferred over tier-level-redundancy.</li>
</ol>
<p>Often, people think of high availability with terms such as the following: <a href="http://en.wikipedia.org/wiki/Round-robin_scheduling">Round Robin</a>, <a href="http://en.wikipedia.org/wiki/Load_balancing_%28computing%29">Load Balancing</a>, and <a href="http://en.wikipedia.org/wiki/Failover">Failover</a>. What do you think of? Leave a comment below with how you meet the trade-offs of designing for HA as well as architectural decisions of low latency.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=syNaBLr_z5c:_YUd0eJuwYk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/syNaBLr_z5c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/</feedburner:origLink></item>
		<item>
		<title>What is grad school for a consultant (or practicing software engineer)</title>
		<link>http://feedproxy.google.com/~r/JAWspeak/~3/DDtn5xDfVwY/</link>
		<comments>http://jawspeak.com/2009/08/10/what-is-grad-school-for-a-consultant-or-practicing-software-engineer/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 00:21:47 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[career]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[gradschool]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=113</guid>
		<description><![CDATA[Reading time: 2 &#8211; 4 minutes

			
				
			
		
Does it make sense for practicing software engineer to go to grad school? Technologies change rapidly, and so do our clients and projects. So we have constant opportunities to learn and most importantly to apply ourselves in building production systems. Bonus: putting production systems live into the world teaches a [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 2 &#8211; 4 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2009%2F08%2F10%2Fwhat-is-grad-school-for-a-consultant-or-practicing-software-engineer%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2009%2F08%2F10%2Fwhat-is-grad-school-for-a-consultant-or-practicing-software-engineer%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>Does it make sense for practicing software engineer to go to grad school? Technologies change rapidly, and so do our clients and projects. So we have constant opportunities to learn <em>and most importantly</em> to apply ourselves in building production systems. Bonus: putting production systems live into the world teaches a lot more than a good grade in an exam.</p>
<p>I once remember in undergrad my friend getting an offer at Microsoft, but he was torn on going to grad school. Basically his sponsor there told him graduate degrees aren&#8217;t worth much, and I&#8217;d go so far as to suggest that they <em>can be</em> less useful than <em>varied and interesting real project work</em>.</p>
<blockquote><p><em>&#8220;Sure, go to cs grad school if it makes your ego feel better, but don&#8217;t do it for your career.&#8221;</em></p></blockquote>
<p>Oh?, my friend said, and if my memory serves me, he went on to grad school.</p>
<p>Everyone&#8217;s situation <em>is </em>different. However this is something I&#8217;ve struggled with for the last several years: does it make sense to step back and do research, and to do computer science-y things instead of day to day project delivery? Maybe. Maybe not. I&#8217;ve more or less made my decision for now. But every few months the nagging urge comes back.</p>
<p>I found these posts helpful for framing my decisions.</p>
<ol>
<li><a rel="nofollow" href="http://jxyzabc.blogspot.com/2008/08/cs-grad-school-part-1-deciding-to-apply.html">http://jxyzabc.blogspot.com/2008/08/cs-grad-school-part-1-deciding-to-apply.html</a> (the whole multi-part series, actually)</li>
<li><a rel="nofollow" href="http://www.stanford.edu/%7Epgbovine/grad-school-app-tips.htm">http://www.stanford.edu/~pgbovine/grad-school-app-tips.htm</a> &#8211; says how it is all about research, and really Ph.D. applications are a job application, where you are applying to do research, rather than a place to be taught. (MBA, Med School, and other higher education avenues are a place you pay to be taught.) Masters degrees are different, but generally still have the same theme &#8220;you&#8217;re getting paid, so you better love (your) research.&#8221;</li>
</ol>
<p><strong>Update: <a href="http://www.markhneedham.com/blog/">Mark </a></strong><a href="http://www.markhneedham.com/blog/"><strong>Needham</strong></a><strong> </strong><strong>commented about two pointed posts from Penelope Trunk&#8217;s blog. Worth reading.<br />
</strong></p>
<ol>
<li><a href="http://blog.penelopetrunk.com/2008/06/18/seven-reasons-why-graduate-school-is-outdated">http://blog.penelopetrunk.com/2008/06/18/seven-reasons-why-graduate-school-is-outdated</a><br />
Grad School isn&#8217;t needed, and it causes more harm than good. Too much focus. Careers change too much. Experience trumps prolonged childlike academic sheltering. (Note: My opinion isn&#8217;t so harsh. <em>Your</em> grad school might not apply, it depends on what you want to do).</li>
<li><a onclick="javascript:pageTracker._trackPageview('/outbound/comment/blog.penelopetrunk.com');" rel="nofollow" href="http://blog.penelopetrunk.com/2009/02/03/dont-try-to-dodge-the-recession-with-grad-school/">http://blog.penelopetrunk.com/2009/02/03/dont-try-to-dodge-the-recession-with-grad-school/</a><br />
She prefers learning by doing, and suggests a feeling of &#8220;being lost&#8221; is actually helpful for growing.</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JAWspeak?a=DDtn5xDfVwY:rQ7t5v95l4Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JAWspeak?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/DDtn5xDfVwY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2009/08/10/what-is-grad-school-for-a-consultant-or-practicing-software-engineer/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://jawspeak.com/2009/08/10/what-is-grad-school-for-a-consultant-or-practicing-software-engineer/</feedburner:origLink></item>
	<media:rating>nonadult</media:rating></channel>
</rss><!-- Dynamic page generated in 2.500 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-03-01 14:24:27 -->
