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

<channel>
	<title>Jason Doucette&#039;s Business By Bootstraps &#187; Howto</title>
	<atom:link href="http://jasondoucette.ca/category/howto/feed/" rel="self" type="application/rss+xml" />
	<link>http://jasondoucette.ca</link>
	<description>Daily thoughts from the trenches of a self-funded company</description>
	<lastBuildDate>Sat, 14 Jan 2012 23:22:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Avoiding the news with the nuclear option</title>
		<link>http://jasondoucette.ca/avoiding-the-news-with-the-nuclear-option/</link>
		<comments>http://jasondoucette.ca/avoiding-the-news-with-the-nuclear-option/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 10:00:18 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Howto]]></category>
		<category><![CDATA[Mindset]]></category>
		<category><![CDATA[bruce schneier]]></category>
		<category><![CDATA[nuclear option]]></category>
		<category><![CDATA[the news]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/?p=529</guid>
		<description><![CDATA[Despite talking about avoiding the news, I&#8217;ll confess that I dip in more often than I should.  I blame my data hoarding tendencies, but I think it started for me a little after 9/11 when I started obsessively checking the headlines every 5-30 minutes to make sure nothing else had blown up. The reality is, something&#8217;s always blowing up in the news.  I think it was Bruce Schneier who pointed out that news is novel; it&#8217;s being reported because it doesn&#8217;t happen every day.  But media organizations have learned what gets attention, and they&#8217;ve gotten really really good at it, [...]]]></description>
			<content:encoded><![CDATA[<p></p><p><img class="aligncenter size-full wp-image-530" title="Scissors by James Bowe" src="http://jasondoucette.ca/wp-content/uploads/2011/11/scissors.jpg" alt="Scissors by James Bowe" width="590" height="255" /></p>
<p>Despite talking about avoiding the news, I&#8217;ll confess that I dip in more often than I should.  I blame my <a href="/tag/data-hoarding/">data hoarding</a> tendencies, but I think it started for me a little after 9/11 when I started obsessively checking the headlines every 5-30 minutes to make sure nothing else had blown up.</p>
<p>The reality is, something&#8217;s always blowing up in the news.  I think it was <a href="http://en.wikipedia.org/wiki/Bruce_Schneier">Bruce Schneier</a> who pointed out that news is novel; it&#8217;s being reported because it doesn&#8217;t happen every day.  But media organizations have learned what gets attention, and they&#8217;ve gotten really really good at it, to the point where, <a href="/giving-people-what-they-want-or-swarm-evolution/">as I mentioned once before</a>, news pretty much boils down to &#8220;bad things are happening that are out of your control, people are getting punished, and hey, sports.&#8221;</p>
<p>My latest excuse for participating in the conversation is that I like to know what&#8217;s happening in Toronto (and not just if things are blowing up.)  But really, I have Twitter for that, so I don&#8217;t have any real reason to go to the home page of the local paper to scan the headlines and get sucked into some horribly stupid bit of poison.</p>
<p>So it seems I can&#8217;t be trusted to police myself, so I&#8217;m invoking the &#8220;avoiding the news nuclear option&#8221;: I&#8217;m blocking new news habit from my browser. Here&#8217;s how you can do it too:</p>
<p>On Windows, you&#8217;ll want to edit c:\windows\system32\drivers\etc\hosts and on the Mac it&#8217;s /etc/hosts &#8211; both will likely require admin privileges.  Then you just add lines like this:</p>
<p>www.sitetoblock.com 127.0.0.1</p>
<p>And you won&#8217;t be able to see them anymore.  If you need back in, just delete the line and save the file again.  There are other software solutions, both for your computer and for your network gear (so your iPad won&#8217;t be a back door in) but this is simple enough for me.</p>
<p>I&#8217;m a little disappointed in myself for having to &#8220;take away the keys&#8221; so to speak, but it&#8217;s time.  I&#8217;ve gained no real benefits and lost too many brain cells and &#8220;mindset points&#8221; to the news already.  Time to cut the cord with a machete and start avoiding the news like a boss.  It&#8217;ll find me if it&#8217;s important enough.</p>
<p>(Oh, and if you&#8217;re curious about the straw that broke my back, have I mentioned about how I try not to complain when I&#8217;m around friends, and don&#8217;t let them do it either, because it becomes a competition to see who has the worse life?  OPSEU, the Ontario government union, made it into an actual contest where people competed to see who was worse off.  My mind was reeling for 20 minutes on that one. No link, because I&#8217;m trying to be responsible.)</p>
<p><em>Photo by <strong id="yui_3_4_0_3_1320720213534_1036"><a href="http://www.flickr.com/photos/jamesrbowe/">James Bowe</a></strong></em></p>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/avoiding-the-news-with-the-nuclear-option/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>oDesk hiring tip: ask for the cat</title>
		<link>http://jasondoucette.ca/odesk-hiring-tip-ask-for-the-cat/</link>
		<comments>http://jasondoucette.ca/odesk-hiring-tip-ask-for-the-cat/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 10:00:35 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Howto]]></category>
		<category><![CDATA[Hiring]]></category>
		<category><![CDATA[hiring decisions]]></category>
		<category><![CDATA[hiring tips]]></category>
		<category><![CDATA[labor]]></category>
		<category><![CDATA[odesk]]></category>
		<category><![CDATA[outsourcing]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/?p=423</guid>
		<description><![CDATA[We&#8217;re expanding again, but this time the needs are either fairly specific and short-term or fairly generic and not requiring close team integration, so it&#8217;s a perfect window of opportunity for some remote outsourcing. I gave oDesk another try after a fairly disastrous earlier hiring attempt a year or two ago, and partly it&#8217;s because of what I&#8217;ve learned since then, but things went much better.  Of the three positions I posted, one has just been filled (by two different people to reduce the company&#8217;s single points of failure,) one is close to closing (it&#8217;s for a client job so [...]]]></description>
			<content:encoded><![CDATA[<p></p><p><a href="http://icanhascheezburger.com/2007/06/06/im-in-ur-office-2/?utm_source=embed&amp;utm_medium=web&amp;utm_campaign=sharewidget"><img class="alignleft" src="http://icanhascheezburger.wordpress.com/files/2007/06/im-in-ur-office-earnin-ur-salry.jpg" alt="I'm in ur office earnin ur salry" width="307" height="409" /></a>We&#8217;re expanding again, but this time the needs are either fairly specific and short-term or fairly generic and not requiring close team integration, so it&#8217;s a perfect window of opportunity for some remote outsourcing.</p>
<p>I gave <a href="http://www.odesk.com">oDesk</a> another try after a fairly disastrous earlier hiring attempt a year or two ago, and partly it&#8217;s because of what I&#8217;ve learned since then, but things went much better.  Of the three positions I posted, one has just been filled (by two different people to reduce the company&#8217;s <a href="http://www.dynamicbusiness.com.au/blogs/does-your-business-have-a-single-point-of-failure.html">single points of failure</a>,) one is close to closing (it&#8217;s for a client job so I need to get some external approvals,) and the other was for a task that I didn&#8217;t think was technically possible, and while we&#8217;ve had some inquiries I haven&#8217;t seen any applicants yet that I&#8217;m confident enough in to make a hiring decision.</p>
<p>Today I want to cover part of the application process, in case it makes anyone else&#8217;s lives easier.  The three key things to remember about hiring on oDesk are that 1) in my opinion and experience, it&#8217;s the most fun recruitment process I&#8217;ve tried, 2) just like any other job posting, you&#8217;re not under any obligation to actually fill the position if you don&#8217;t like any of the applicants, and 3) you&#8217;re going to get swamped with applicants and it could seriously eat up a few days of your time if you&#8217;re not careful.</p>
<p>Today&#8217;s post is about avoiding that time suck by asking for the cat.</p>
<p>&#8220;Asking for the cat&#8221; is a phrase I came up with at an old job, where I made sure to put in every job posting that applicants needed to include a link to an <a href="http://en.wikipedia.org/wiki/Lolcat">LOLcat</a>, except I didn&#8217;t include that helpful hyperlink to what an LOLcat was, because I wanted to make people work a little.</p>
<p>I don&#8217;t actually care which picture gets sent in, and actually, I&#8217;ve changed my process to be even simpler now, like asking for a favourite food, or the name of the President of the USA, because there are some cultures who I think took my cat picture request the wrong way, and as you&#8217;ll find if you try it, the barrier to application really doesn&#8217;t have to be that high. I still call the act of including a random but required question asking for the cat though.</p>
<p>So why do I ask?  Here&#8217;s the thing: when you post to one of these job sites, you&#8217;re going to get hit with a ton of responses.  And you&#8217;re going to take up a bunch of time reading them, and you&#8217;re also going to think each of the applications is totally amazing. What you might not realize, at least at first, is that most of the applicants didn&#8217;t even read your posting.  They&#8217;re just automatically applying for every job that comes up that meets their criteria.  The cat is just <a href="http://www.snopes.com/music/artists/vanhalen.asp">a bowl of M&amp;Ms with the brown ones removed</a>, really &#8211; a basic test to see if the applicant can follow the simplest of instructions.</p>
<p>And if the question doesn&#8217;t get answered, the application is denied without a second glance. No exceptions.  I&#8217;ll admit, it&#8217;s hard sometimes, especially if the field of qualified applicants who followed instructions is small, but you really need to ask yourself how bad things could get if you start out like this.</p>
<p>In my experience hiring on oDesk so far, a little under 20% of applicants pass this test, which means if you use this trick, you just went from, say, ten hours reviewing resumes and shortlisting candidates to less than two.</p>
<p>You&#8217;re welcome. <img src='http://jasondoucette.ca/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/odesk-hiring-tip-ask-for-the-cat/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New on LGG: how to quickly make a mobile version of a site</title>
		<link>http://jasondoucette.ca/new-on-lgg-how-to-quickly-make-a-mobile-version-of-a-site/</link>
		<comments>http://jasondoucette.ca/new-on-lgg-how-to-quickly-make-a-mobile-version-of-a-site/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 15:51:20 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Howto]]></category>
		<category><![CDATA[LGG]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/?p=97</guid>
		<description><![CDATA[Over at LGG Media, we&#8217;ve started sharing some of the stuff we do in a series of Technical Notes (OK, there&#8217;s only one right now, but it&#8217;ll be a series, honest!).  We&#8217;re releasing them as PDFs because&#8230; wait for it&#8230; yes, I frigging hate formatting source code in HTML even with a good plugin. In the first note, we go over a new technique we&#8217;ve developed with Microsoft&#8217;s ASP.NET MVC framework to easily make WAP, iPhone optimized and other versions of a web page without duplicating any code or otherwise creating a maintenance nightmare. This is my first &#8220;technical article&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Over at <a href="http://www.lggmedia.com">LGG Media</a>, we&#8217;ve started sharing some of the stuff we do in a series of <a href="http://lggmedia.com/TechnicalNotes/">Technical Notes</a> (OK, there&#8217;s only one right now, but it&#8217;ll be a series, honest!).  We&#8217;re releasing them as PDFs because&#8230; wait for it&#8230; yes, I frigging hate formatting source code in HTML even with a good plugin.</p>
<p>In the first note, we go over a new technique we&#8217;ve developed with Microsoft&#8217;s ASP.NET MVC framework to easily make WAP, iPhone optimized and other versions of a web page without duplicating any code or otherwise creating a maintenance nightmare.</p>
<p>This is my first &#8220;technical article&#8221; and I&#8217;m sure there are a lot of other ways to exploit this technique, so comments are more than welcome &#8211; let me know what you think!  You can see the note (and all future ones) <a href="http://lggmedia.com/TechnicalNotes/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/new-on-lgg-how-to-quickly-make-a-mobile-version-of-a-site/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to use Craigslist to hire effectively</title>
		<link>http://jasondoucette.ca/how-to-use-craigslist-to-hire-effectively/</link>
		<comments>http://jasondoucette.ca/how-to-use-craigslist-to-hire-effectively/#comments</comments>
		<pubDate>Wed, 08 Oct 2008 11:06:18 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Howto]]></category>
		<category><![CDATA[Craigslist]]></category>
		<category><![CDATA[Hiring]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/?p=44</guid>
		<description><![CDATA[So it looks like Scoble&#8217;s discovered the joys of hiring via Craigslist: the signal to noise ratio is off the charts bad.  I don&#8217;t know if this is the first time he&#8217;s tried it, but judging from the helpful list of tips for job seekers, he probably went through the standard emotional ride: Step 1) Wow, 90 responses for free!  Take that, paid job posting services! Step 2) Wow, how can people be so bad at job hunting? (Though actually, I&#8217;m not sure if he&#8217;s posting in one of the areas where ads cost money &#8211; all sections are free [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>So it looks like Scoble&#8217;s discovered the joys of hiring via Craigslist: the signal to noise ratio is off the charts bad.  I don&#8217;t know if this is the first time he&#8217;s tried it, but judging from the <a href="http://scobleizer.com/2008/10/05/need-a-job-resume/">helpful list of tips for job seekers</a>, he probably went through the standard emotional ride:</p>
<p>Step 1) Wow, 90 responses for free!  Take that, paid job posting services!</p>
<p>Step 2) Wow, how can people be so bad at job hunting?</p>
<p>(Though actually, I&#8217;m not sure if he&#8217;s posting in one of the areas where ads cost money &#8211; all sections are free here in Toronto.)</p>
<p>I&#8217;ve hired via postings on Craigslist three times, and I&#8217;m interviewing someone else tomorrow that I found on their &#8220;gigs wanted&#8221; section, so there&#8217;s certainly some good stuff on there.  The first time I went through the process, I was over the moon happy.  In my last job at a big company, I managed to get all of 5 resumes from HR, and none of them were particularly stellar.  Now here I was with 50!  That I found myself!  For free!</p>
<p>Of course, most of them were crap.  In hindsight, all but about 3 of them, actually.  Pretty much everything Scoble says not to do, someone did. And I doubt it&#8217;s a problem with Craigslist &#8211; if someone&#8217;s looking for work there, they&#8217;re probably also looking for work on the paid posting sites.</p>
<p>So here&#8217;s the secret to successful Craigslist postings: add as many hoops and puzzles as you can.</p>
<p>If you want a job with our company, you have to send a picture of an LOLcat.  I won&#8217;t look at a resume that doesn&#8217;t have one.  It&#8217;s a simple test of knowledge of either a) internet culture or b) Google.</p>
<p>Then I ask for something else, like a list of 5 reasons why you&#8217;re awesome, because why would I want to hire someone who&#8217;s not awesome?  Sometimes the answers we get back are more reasons not to hire than to hire, which was unexpected.</p>
<p>I&#8217;ll also usually make up some technology requirement that I can&#8217;t find on Google. I haven&#8217;t seen someone take credit as an expert in B495 Gaussianization Protocol R yet, but it&#8217;s big bonus points if someone admits they don&#8217;t know it or asks what it is.</p>
<p>I stopped at the &#8220;send me a video of you explaining algorithm X&#8221; stage, but you get the idea: if someone&#8217;s not willing to do some basic work to submit a resume, they&#8217;re probably not going to go the extra mile when things go south on a project.  Showing up to work might be a stretch task for some people &#8211; I&#8217;ve had interviews where I had to do everything in my power to not ask &#8220;so, do you actually want a job?&#8221;</p>
<p>Speaking of interviews &#8211; these posting steps are all pre-screen techniques, but if someone passes the initial tests, that doesn&#8217;t mean you don&#8217;t have to do a phone screen next.  There are all kinds of reasons why someone might be a bad fit, and a 20 minute phone call is a much better use of everyone&#8217;s time than an hour or more of in person discussion, plus prep, clearing schedules, etc.</p>
<p>Any other ideas to help job posters? Got any examples of cool job postings that pre-test the candidates?  Post &#8216;em in the comments or ping me on <a href="http://twitter.com/jasondoucette">the Twitter</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/how-to-use-craigslist-to-hire-effectively/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inbox Zero and Simplification</title>
		<link>http://jasondoucette.ca/inbox-zero-and-simplification/</link>
		<comments>http://jasondoucette.ca/inbox-zero-and-simplification/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 16:28:03 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[GTD]]></category>
		<category><![CDATA[Howto]]></category>
		<category><![CDATA[Inbox Zero]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/2008/08/14/inbox-zero-and-simplification/</guid>
		<description><![CDATA[Having finally achieved a count of zero in all my inboxes (1 work, 1 personal, and 2 for various projects), the trick now is staying on top of them. I&#8217;m sure it&#8217;s been written a bunch of times, but an inbox isn&#8217;t a to-do list, and shouldn&#8217;t be treated as one.  I&#8217;ll admit, I get a bit lazy still, so if I know something&#8217;s going to be dealt with in the next 48 hours, I&#8217;ll leave it there as a reminder, but everything else either gets archived, deleted, responded, or deferred. But where do they get deferred to?  I&#8217;ve tried [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Having finally achieved a count of zero in all my inboxes (1 work, 1 personal, and 2 for various projects), the trick now is staying on top of them.</p>
<p>I&#8217;m sure it&#8217;s been written a bunch of times, but an inbox isn&#8217;t a to-do list, and shouldn&#8217;t be treated as one.  I&#8217;ll admit, I get a bit lazy still, so if I know something&#8217;s going to be dealt with in the next 48 hours, I&#8217;ll leave it there as a reminder, but everything else either gets archived, deleted, responded, or deferred.</p>
<p>But where do they get deferred to?  I&#8217;ve tried the @review, @respond etc folders that the David Allen camp seems to like, but they just become other inboxes for me, and they&#8217;re inboxes I never remember to check, so that&#8217;s turned into the best way to lose mail for weeks.</p>
<p>For work stuff, I throw my todos into <a href="http://www.fogcreek.com/FogBugz/">FogBugz</a> along with the bugs, features, and inquiries that it already handles.  Those mails are usually tied to a project, so I haven&#8217;t had to make up a &#8220;Jason&#8217;s crap&#8221; project yet, but I&#8217;m not against the idea.  It&#8217;s also not a bad thing if co-workers can see what I&#8217;m up to anyway.</p>
<p>I have a personal FogBugz license, but I don&#8217;t have a central host to put it on right now, so instead I&#8217;ve switched to using <a href="http://backpackit.com/">Backpack</a>.   Thefree plan works fine, and almost encourages the kind of simplification that the 37signals gang tends to encourage &#8211; every major category gets a page, but with the free plan you only get 5 pages.</p>
<p>If I have more than 5 categories of &#8220;to do&#8221; type stuff on the go, it&#8217;s time to either crunch down and finish one or more or let something go and delete the page/category.</p>
<p>I used to do this with my inbox/todo list, but in that case I&#8217;d finally give up on the items that were, say 3 months old, and I&#8217;d feel bad about it not just when I delete the mail but every single day.  This new system will, I hope, give me a better sense of what I&#8217;m up to and how deep I&#8217;m in it.</p>
<p>The only downside is I hate spam even more now. It&#8217;s like a pigeon pooping on my newly washed car.</p>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/inbox-zero-and-simplification/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Troubleshooting MySQL connection pool timeouts in ADO.NET</title>
		<link>http://jasondoucette.ca/troubleshooting-mysql-connection-pool-timeouts-in-adonet/</link>
		<comments>http://jasondoucette.ca/troubleshooting-mysql-connection-pool-timeouts-in-adonet/#comments</comments>
		<pubDate>Sat, 21 Jun 2008 16:14:07 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[Howto]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL ADO.NET]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/2008/06/21/troubleshooting-mysql-connection-pool-timeouts-in-adonet/</guid>
		<description><![CDATA[Twitter followers: this post deals with MySQL troubleshooting which might not mean anything to you, depending on why you follow me. Still, welcome! Here&#8217;s a funny cat picture for you! Since I spent a chunk of my Saturday figuring this one out and there didn&#8217;t seem to be a lot of existing guidance online (maybe because not too many people are BRILLIANT GENIUSES who use ASP.NET with MySQL, and I&#8217;m not being sarcastic, it&#8217;s really my favourite thing ever, and if you&#8217;re also a BRILLIANT GENIUS, let&#8217;s talk), I thought I&#8217;d share. This paragraph serves no actual purpose other than [...]]]></description>
			<content:encoded><![CDATA[<p></p><p><a href="http://twitter.com/jasondoucette">Twitter followers</a>: this post deals with MySQL troubleshooting which might not mean anything to you, depending on why you follow me.  Still, welcome!  Here&#8217;s a <a href="http://i3.photobucket.com/albums/y90/oneniisama/flavor.jpg">funny cat picture</a> for you!</p>
<p>Since I spent a chunk of my Saturday figuring this one out and there didn&#8217;t seem to be a lot of existing guidance online (maybe because not too many people are BRILLIANT GENIUSES who use ASP.NET with MySQL, and I&#8217;m not being sarcastic, it&#8217;s really my favourite thing ever, and if you&#8217;re also a BRILLIANT GENIUS, let&#8217;s talk), I thought I&#8217;d share.</p>
<p>This paragraph serves no actual purpose other than to explain that the error text below isn&#8217;t an actual error, it&#8217;s the message that&#8217;s appearing in our logs that we want to fix.  Nothing to do with this blog&#8217;s software, which at this time doesn&#8217;t event use .NET.  Anyway:</p>
<p><span class="clsBlurb"> </span></p>
<p class="MsoNormal"><span style="font-size: 8pt; font-family: 'Courier New'">Exception: System.InvalidOperationException<br />
Message: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.<br />
</span></p>
<p>Yeah, that sucks. Plus it doesn&#8217;t happen all the time. But it could happen anytime. Did I mention it sucks?</p>
<p>A brief backgrounder before we fix the problem:</p>
<p>The MySQL connector for ADO.NET has the option of using a thing called a connection pool to speed up performance. You&#8217;ve probably heard this already, but database operations are generally cheap, performance-wise, but connections are expensive. Your connector can basically cache these connections for you.</p>
<p>Every time you connect to MySQL, you need a connection (duh). If your previous connection didn&#8217;t close down properly, the connector can&#8217;t give you that old one again, because it&#8217;s still in use. There are all kinds of reasons why this might happen, but since we are BRILLIANT GENIUSES we don&#8217;t need to know them all, we just need to know how to find them and stomp them flat.</p>
<p>(I&#8217;ll just point out that even if you close the connection, if you didn&#8217;t close the resources using the connection (like, for example, a DataReader), the connection will stay in use. You know, not like that happened to us today or anything, just saying.)</p>
<p>So, first off, how can you tell if you&#8217;ve got a potential leak? One way is to wait for the exception to show up in production. Another is to load test your application, but the trick is that you&#8217;ll need to hit the part of your code that&#8217;s failing with the load test, which may not happen if it&#8217;s obscure enough.</p>
<p>The way I&#8217;ll show you now is to run a MySQL command called <a href="http://dev.mysql.com/doc/refman/5.0/en/show-processlist.html">SHOW FULL PROCESSLIST</a>.</p>
<p>This&#8217;ll give you a dump of all the active threads in MySQL, along with the username, client host, and database that&#8217;s involved. You can run this in your development environment. Depending on your setup, you might have one, two, or seventeen of these things (or some other number greater than zero), Don&#8217;t worry too much about the exact number. The key is that the number of open threads shouldn&#8217;t be rising as you walk through your application.</p>
<p>OK, so now we&#8217;ve managed to find a situation in our test environment (which isn&#8217;t called &#8220;prod,&#8221; right?) where the number of open threads starts at one number, and then we do a repeatable sequence of actions in the app, and the number of open threads increases. And it keeps increasing every time we do that sequence of actions until we hit 100 or so (your default may vary) and then you can&#8217;t use the system anymore.</p>
<p>Yay!</p>
<p>From here it&#8217;s a pretty straightforward process with either a debugger or, uh, commenting out blocks of code (what, my home machine has issues with the debugger, stop laughing) until you find the call that&#8217;s failing. Fix that, run some more tests with periodic checks to the process list, and you&#8217;re all good.</p>
<p>OK, so I don&#8217;t want this to ever happen again. How can I modify my build process to test for this kind of thing? Guess what? I&#8217;ve got a plan!</p>
<p>All of our data access routines are done by Factory objects. I&#8217;m still debating whether or not to call them Managers like they do in <a href="http://www.amazon.com/gp/redirect.html%3FASIN=0321127420%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/Enterprise-Application-Architecture-Addison-Wesley-Signature/dp/0321127420%253FSubscriptionId=1EAVZ3Z1N77P2JA3QY82" title="$TEXT">Patterns of Enterprise Application Architecture</a>, but they create <a href="http://en.wikipedia.org/wiki/Data_Transfer_Object" title="DTOs">DTOs</a>, so I&#8217;m comfortable with the Factory idea, at least for the loads. But I digress. Furthermore, all of our data routines are usually named something starting with the word &#8220;Load.&#8221; So, the theory goes, if I create an integration-level unit test (I don&#8217;t want to run this all the time, just before checkins) that uses reflection to find all the classes that end in &#8220;Factory&#8221; and run all the public methods inside that start with &#8220;Load&#8221; 150 times I think we&#8217;ll have about 97% certainty that we haven&#8217;t introduced any new<br />
leaks. We&#8217;ll see how that goes &#8211; it can wait until Monday when I&#8217;m in an environment that doesn&#8217;t include a fridge full of beer.</p>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/troubleshooting-mysql-connection-pool-timeouts-in-adonet/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>An actual key to the office is semi-prestigious but not as cool</title>
		<link>http://jasondoucette.ca/an-actual-key-to-the-office-is-semi-prestigious-but-not-as-cool/</link>
		<comments>http://jasondoucette.ca/an-actual-key-to-the-office-is-semi-prestigious-but-not-as-cool/#comments</comments>
		<pubDate>Mon, 25 Feb 2008 11:59:58 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Howto]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/2008/02/25/an-actual-key-to-the-office-is-semi-prestigious-but-not-as-cool/</guid>
		<description><![CDATA[Stolen shamelessly from this 37 Signals thread because I couldn&#8217;t find an official place to steal it from, but getting through the security gate each morning was the highlight of my day at my old job, and I&#8217;m pretty sure I let everyone know. (Yes, tagged with howto) Technorati Tags: Dilbert]]></description>
			<content:encoded><![CDATA[<p></p><p><img src="http://jasondoucette.ca/wp-content/uploads/2008/02/1454501568-6b3edb3c2b-o.png" height="173" width="450" border="1" hspace="4" vspace="4" /><br />
Stolen shamelessly from <a href="http://www.37signals.com/svn/posts/874-behind-the-scenes-at-37signals-miscellaneous">this 37 Signals thread</a> because I couldn&#8217;t find an official place to steal it from, but getting through the security gate each morning was the highlight of my day at my old job, and I&#8217;m pretty sure I let everyone know.</p>
<p>(Yes, tagged with howto)<br />
<!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/Dilbert" rel="tag">Dilbert</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/an-actual-key-to-the-office-is-semi-prestigious-but-not-as-cool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Regex: Make sure a phone number is 10 digits</title>
		<link>http://jasondoucette.ca/regex-make-sure-a-phone-number-is-10-digits/</link>
		<comments>http://jasondoucette.ca/regex-make-sure-a-phone-number-is-10-digits/#comments</comments>
		<pubDate>Sat, 09 Feb 2008 17:06:40 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[Howto]]></category>
		<category><![CDATA[Regular Expressions]]></category>
		<category><![CDATA[Validators]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/2008/02/09/regex-make-sure-a-phone-number-is-10-digits/</guid>
		<description><![CDATA[I needed a generic validator for a phone number, and I started thinking about the format of the number but at the end of the day I just want to be sure that there are 10 digits in the entry, and the user can decorate that however he or she like with brackets, hyphens, dots and spaces, but as long as there are 10 digits in the mix and there aren&#8217;t any clearly invalid characters like letters or weird punctuation, I&#8217;m good. So: a regex to make sure that a string contains at least 10 digits along with any optional [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I needed a generic validator for a phone number, and I started thinking about the format of the number but at the end of the day I just want to be sure that there are 10 digits in the entry, and the user can decorate that however he or she like with brackets, hyphens, dots and spaces, but as long as there are 10 digits in the mix and there aren&#8217;t any clearly invalid characters like letters or weird punctuation, I&#8217;m good.</p>
<p>So: a regex to make sure that a string contains at least 10 digits along with any optional spaces, dashes, brackets and dots:<br />
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<p class="csharpcode">&nbsp;</p>
<div class="csharpcode">
<pre><span class="lnum">   1:  </span>Regex tester = <span class="kwrd">new</span> Regex(<span class="str">@"^([-() ]*\d[-() .]*){10}$"</span>);</pre>
<pre><span class="lnum">   2:  </span></pre>
<pre><span class="lnum">   3:  </span>Assert.IsTrue(tester.IsMatch(<span class="str">"123-456-7890"</span>));</pre>
<pre><span class="lnum">   4:  </span>Assert.IsTrue(tester.IsMatch(<span class="str">"123 456 7890"</span>));</pre>
<pre><span class="lnum">   5:  </span>Assert.IsTrue(tester.IsMatch(<span class="str">"1234567890"</span>));</pre>
<pre><span class="lnum">   6:  </span>Assert.IsTrue(tester.IsMatch(<span class="str">"(123) 456-7890"</span>));</pre>
<pre><span class="lnum">   7:  </span>Assert.IsTrue(tester.IsMatch(<span class="str">"123.456.7890"</span>));</pre>
<pre><span class="lnum">   8:  </span>Assert.IsTrue(tester.IsMatch(<span class="str">"123 4567890"</span>));</pre>
<pre><span class="lnum">   9:  </span></pre>
<pre><span class="lnum">  10:  </span>Assert.IsFalse(tester.IsMatch(<span class="str">""</span>));</pre>
<pre><span class="lnum">  11:  </span>Assert.IsFalse(tester.IsMatch(<span class="str">"123"</span>));</pre>
<pre><span class="lnum">  12:  </span>Assert.IsFalse(tester.IsMatch(<span class="str">"werew"</span>));</pre>
<pre><span class="lnum">  13:  </span>Assert.IsFalse(tester.IsMatch(<span class="str">"12345678901"</span>));</pre>
<pre><span class="lnum">  14:  </span>Assert.IsFalse(tester.IsMatch(<span class="str">"123x567890"</span>));</pre>
<pre><span class="lnum">  15:  </span>Assert.IsFalse(tester.IsMatch(<span class="str">"123-456-7890 x32"</span>));</pre>
<pre><span class="lnum">  16:  </span>Assert.IsFalse(tester.IsMatch(<span class="str">"123-456-7890x"</span>));</pre>
</div>
<p>It&#8217;s up to the application to filter and reformat the entry for internal storage.  I like just storing the digits so later applications can reformat as needed, so I go with something like this:<br />
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<p class="csharpcode">&nbsp;</p>
<div class="csharpcode">
<pre><span class="lnum">   1:  </span><span class="kwrd">string</span> enteredNumber = <span class="str">"(123) 456-7890"</span>;</pre>
<pre><span class="lnum">   2:  </span><span class="kwrd">string</span> justDigits =</pre>
<pre><span class="lnum">   3:  </span>    <span class="kwrd">new</span> Regex(<span class="str">@"[^\d]"</span>).Replace(enteredNumber, <span class="str">""</span>);</pre>
<pre><span class="lnum">   4:  </span>Assert.AreEqual(<span class="str">"1234567890"</span>, justDigits);</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/regex-make-sure-a-phone-number-is-10-digits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating dynamic dates for MySQL test data</title>
		<link>http://jasondoucette.ca/generating-dynamic-dates-for-mysql-test-data/</link>
		<comments>http://jasondoucette.ca/generating-dynamic-dates-for-mysql-test-data/#comments</comments>
		<pubDate>Fri, 08 Feb 2008 15:42:12 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Howto]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[test data]]></category>
		<category><![CDATA[test suite]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/2008/02/08/generating-dynamic-dates-for-mysql-test-data/</guid>
		<description><![CDATA[A quickie MySQL tip: I&#8217;ve been working on creating a standard testbed of data (more on that someday) for one of our apps, and the issue of dates came up.  Dates can be a problem in test data if they&#8217;re being compared to today&#8217;s date, i.e. if it matters if the date field represents something in the past, present or future. No problem, I thought, instead of setting something up with a string literal, like date_field = "2008-03-04 12:00:00" (Assume that&#8217;s inside an insert or update command&#8230;) I&#8217;d build the string based on the current date, so a field would [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>A quickie MySQL tip:</p>
<p>I&#8217;ve been working on creating a standard testbed of data (more on that someday) for one of our apps, and the issue of dates came up.  Dates can be a problem in test data if they&#8217;re being compared to today&#8217;s date, i.e. if it matters if the date field represents something in the past, present or future.</p>
<p>No problem, I thought, instead of setting something up with a string literal, like</p>
<pre>date_field = "2008-03-04 12:00:00"</pre>
<p>(Assume that&#8217;s inside an insert or update command&#8230;)</p>
<p>I&#8217;d build the string based on the current date, so a field would always be, say, 5 days in the future (assuming the testbed is repopulated daily through an automated job):</p>
<pre>date_field = date(date_add(now(), interval 5 day)) + " 12:00:00"</pre>
<p>That, as it turns out, doesn&#8217;t work so well.  (Oh, another quick tip, check your data after setting up a test suite before going nuts over where your code might be failing).  A quick, easy, and &#8220;should have done this in the first place&#8221; check reveals:</p>
<pre>+-----------------------------------------------------+
| date(date_add(now(), interval 5 day)) + " 12:00:00" |
+-----------------------------------------------------+
|                                                2020 |
+-----------------------------------------------------+</pre>
<p>I ended up going with something like this:</p>
<pre>date_field = date_format(date_add(now(), interval 5 day), "%Y-%m-%d 12:00:00")</pre>
<p>Much better&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/generating-dynamic-dates-for-mysql-test-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to enable the Goto Line command in Notepad</title>
		<link>http://jasondoucette.ca/how-to-enable-the-goto-line-command-in-notepad/</link>
		<comments>http://jasondoucette.ca/how-to-enable-the-goto-line-command-in-notepad/#comments</comments>
		<pubDate>Fri, 21 Dec 2007 12:23:26 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Howto]]></category>

		<guid isPermaLink="false">http://jasondoucette.ca/2007/12/21/how-to-enable-the-goto-line-command-in-notepad/</guid>
		<description><![CDATA[This was driving me nuts during a recent server migration where Notepad was the most readily available troubleshooting tool &#8211; sometimes I&#8217;d hit Control-G and a &#8220;goto line number:&#8221; prompt would appear, and sometimes it wouldn&#8217;t. As it turns out, the Goto command in Notepad is only enabled when word wrap is turned off. Ah.  Better.]]></description>
			<content:encoded><![CDATA[<p></p><p>This was driving me nuts during a recent server migration where Notepad was the most readily available troubleshooting tool &#8211; sometimes I&#8217;d hit Control-G and a &#8220;goto line number:&#8221; prompt would appear, and sometimes it wouldn&#8217;t.</p>
<p>As it turns out, the Goto command in Notepad is only enabled when word wrap is turned off.</p>
<p>Ah.  Better.</p>
]]></content:encoded>
			<wfw:commentRss>http://jasondoucette.ca/how-to-enable-the-goto-line-command-in-notepad/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

