<?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>All Night Diner &#187; code</title>
	<atom:link href="http://micropipes.com/blog/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://micropipes.com/blog</link>
	<description>because at 3am anything sounds good</description>
	<lastBuildDate>Sun, 15 Aug 2010 16:35:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>CLI Split Windows in Vim</title>
		<link>http://micropipes.com/blog/2010/08/13/cli-split-windows-in-vim/</link>
		<comments>http://micropipes.com/blog/2010/08/13/cli-split-windows-in-vim/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 21:36:19 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[blah blah]]></category>
		<category><![CDATA[open web]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/?p=170</guid>
		<description><![CDATA[I use split windows, both horizontally and vertically, in Vim all the time. I&#8217;ve always wanted to be able to split the window and then start a command line shell within that window but up until now that has just been a dream. My friend sent me a link to conque this morning which I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>I use split windows, both horizontally and vertically, in <a href="http://www.vim.org/">Vim</a> all the time.  I&#8217;ve always wanted to be able to split the window and then start a command line shell within that window but up until now that has just been a dream.</p>
<p><a href="http://hopson.ws/blog/">My friend</a> sent me a link to <a href="http://code.google.com/p/conque/">conque</a> this morning which I&#8217;m so taken with that it&#8217;s prompted me to drop coding and write a blog post.</p>
<p>Conque lets me do exactly what I&#8217;ve wanted, create shells within Vim.  In insert mode you interact with the shell as expected.  In normal mode you can scroll back through your history, yank text into buffers, paste and manipulate text.  Best thing ever.</p>
<p><a href="http://micropipes.com/blog/wp-content/img/vim_cli.png"><img src="http://micropipes.com/blog/wp-content/img/vim_cli_small.png" /></a><br />
<caption>Two files open on the left, three shells on the right; iPython, MySQL, and Django&#8217;s web server &#8211; all with syntax highlighting.</caption>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2010/08/13/cli-split-windows-in-vim/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>addons.mozilla.org ♥s unit tests.  Again.</title>
		<link>http://micropipes.com/blog/2010/05/03/addons-mozilla-org-%e2%99%a5s-unit-tests-again/</link>
		<comments>http://micropipes.com/blog/2010/05/03/addons-mozilla-org-%e2%99%a5s-unit-tests-again/#comments</comments>
		<pubDate>Mon, 03 May 2010 17:34:44 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[AMO]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/?p=142</guid>
		<description><![CDATA[AMO has had an on-again off-again relationship with unit tests. A little over a year ago we had a thousand unit tests that sort of, mostly, ran. The problem is, PHP unit testing just isn&#8217;t as good as it should be. CakePHP relies on SimpleTest, one of the main PHP test suites. It worked relatively [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://addons.mozilla.org">AMO</a> has had an on-again off-again relationship with unit tests.  A little over a year ago we had <a href="http://micropipes.com/blog/2009/04/09/addonsmozillaorg-celebrates-1000-passing-unit-tests/">a thousand unit tests</a> that sort of, mostly, ran.  The problem is, PHP unit testing just isn&#8217;t as good as it should be.  CakePHP relies on <a href="http://www.simpletest.org/">SimpleTest</a>, one of the main PHP test suites.  It worked relatively well for a small number of tests, but as our suite grew, so did our troubles.</p>
<p>Our main issue was hitting a memory limit or the max execution time.  We hit the limits often for a variety of reasons, some legitimate bugs, and some because we tried to hack around things to make the tests run.  If we change the limits we affect the tests because they are running within the same environment.  There wasn&#8217;t really a concept of fixtures then, although it looks like <a href="http://bakery.cakephp.org/articles/view/testing-models-with-cakephp-1-2-test-suite">CakePHP has stepped up there</a>.  The simple test web runner was hard to use and the mock objects were sometimes a little too mocked and missing some attributes.</p>
<p>All in all it was a heroic effort to get that many tests, but we didn&#8217;t maintain it because they were so slow to write and difficult to run.  Testing can be a pain to write, sure, but it shouldn&#8217;t be a burden like that.  Enter <a href="http://docs.djangoproject.com/en/dev/topics/testing/">Django&#8217;s testing suite</a> (built on top of <a href="http://docs.python.org/library/unittest.html">Python&#8217;s unittest</a>).  It has most of our complaints handled out of the box.  It&#8217;s very well documented, considers a lot of aspects of testing, supports fixtures, a built-in client, etc.  It&#8217;s a well thought out framework to build tests on.</p>
<p>We&#8217;re being more vigilant about requiring tests this time around, but they also aren&#8217;t as frustrating to write.  When you write them they actually work and they stay working.  Most of what you want is built in already.  For example, I wrote the password reset form we needed on AMO in Django.  With CakePHP and SimpleTest I&#8217;d have no idea how to test that the email was actually working.  It&#8217;s apparently possible <a href="http://www.curioussymbols.com/simplemail/">with a SimpleTest add-on</a> and enough code that I have to scroll in my browser.  With Django&#8217;s test suite the actual code was 5 lines, 3 of which were assertions:</p>
<pre><code class="python">
    def test_request_success(self):
        self.client.post('/en-US/firefox/users/pwreset',
                        {'email': self.user.email})

        eq_(len(mail.outbox), 1)
        assert mail.outbox[0].subject.find('Password reset') == 0
        assert mail.outbox[0].body.find('pwreset/%s' % self.uidb36) > 0
</code></pre>
<p>With the power of the new test suite we&#8217;re once again writing and maintaining our unit tests &#8211; currently at around 390 tests and increasing steadily.  Plenty of people have written about why unit tests are important so I won&#8217;t belabor the point, but I will mention that it&#8217;s a great feeling to be able to commit something and be confident it hasn&#8217;t affected other parts of the site.  It&#8217;s almost as good of a feeling when you write your code and a completely different test fails pointing out a case that you didn&#8217;t even consider but one that would soak up developer time trying to debug down the road.  </p>
<p>Building on a foundation that takes testing seriously is great.</p>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2010/05/03/addons-mozilla-org-%e2%99%a5s-unit-tests-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Libraries to connect to a Citrix NetScaler or Zeus Traffic Manager</title>
		<link>http://micropipes.com/blog/2010/03/23/libraries-to-connect-to-a-citrix-netscaler-or-zeus-traffic-manager/</link>
		<comments>http://micropipes.com/blog/2010/03/23/libraries-to-connect-to-a-citrix-netscaler-or-zeus-traffic-manager/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 18:56:57 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[AMO]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/?p=133</guid>
		<description><![CDATA[The first front end cache we used on AMO was the Citrix NetScaler. I&#8217;ve complained about it&#8217;s API before but apparently never announced the library I wrote to purge items from the cache. So, a little late, but I have some reusable PHP code that will talk to your NetScaler and let you expire objects. [...]]]></description>
			<content:encoded><![CDATA[<p>The first front end cache we used on <a href="https://addons.mozilla.org/">AMO</a> was the <a href="http://www.citrix.com/English/ps2/products/product.asp?contentID=21679">Citrix NetScaler</a>.  I&#8217;ve <a href="http://micropipes.com/blog/2008/07/14/planning-your-api-is-important/">complained about it&#8217;s API before</a> but apparently never announced the library I wrote to purge items from the cache.  So, a little late, but I have <a href="http://viewvc.svn.mozilla.org/vc/libs/ns-api/">some reusable PHP code that will talk to your NetScaler</a> and let you expire objects.</p>
<p>We hit some limitations with the NetScaler that we weren&#8217;t happy with.  Cost aside, it ignored some pretty standard stuff like the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44">HTTP Vary Header</a>.  After working around that for years we switched to the horizontally scalable <a href="http://www.zeus.com/products/traffic-manager/index.html">Zeus Traffic Manager</a> (at that time, referred to as ZXTM).  We&#8217;ve been pleased with our choice and six months ago I wrote a <a href="http://viewvc.svn.mozilla.org/vc/libs/zxtm-api/">similar PHP library that allows you to connect to Zeus&#8217;s API</a>.  Time and priorities being what they are, we never implemented it in production.</p>
<p>Finally, the real point to this post, last night I wrote a <a href="http://github.com/clouserw/hera">python library that will expire content from Zeus</a>.  We&#8217;ll roll this into our migration and waiting on content to expire from Zeus should be a thing of the past.</p>
<p>As always, if you can use the libraries, feel free.  They all have READMEs with examples.</p>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2010/03/23/libraries-to-connect-to-a-citrix-netscaler-or-zeus-traffic-manager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maintaining localization between Python and PHP (it&#8217;s not fun)</title>
		<link>http://micropipes.com/blog/2010/03/08/maintaining-localization-between-python-and-php-its-not-fun/</link>
		<comments>http://micropipes.com/blog/2010/03/08/maintaining-localization-between-python-and-php-its-not-fun/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 22:42:00 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[AMO]]></category>
		<category><![CDATA[L10n]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/?p=115</guid>
		<description><![CDATA[I reached my hand into the barrel of problems our migration to Python is going to cause and came up with Localization. It figures. First out of the chute was the .po files. It turns out the actual formatting is different between the two languages. PHP uses %1$s for its substitutions, but python uses either [...]]]></description>
			<content:encoded><![CDATA[<p>I reached my hand into the barrel of problems <a href="http://micropipes.com/blog/2009/11/17/amo-development-changes-in-2010/">our migration to Python</a> is going to cause and came up with Localization.  It figures.</p>
<p>First out of the chute was the .po files.  It turns out the actual formatting is different between the two languages.  PHP uses <em>%1$s</em> for its substitutions, but python uses either named variables like <em>(num)s</em> or integers like <em>{0}</em>.  For the record, they both support <em>%s</em> when you don&#8217;t need to order the substitutions.<br />
PHP example:<br />
<code>I have %2$s apples and %1$s oranges</code><br />
Python example:<br />
<code>I have {1} apples and {0} oranges</code></p>
<p>Since I&#8217;ve worked with the <a href="http://translate.sourceforge.net/wiki/">Translate Toolkit</a> before, I decided to write a script to convert between the two formats.  If you find yourself in the same unfortunate boat as me, behold<br />
<a href="http://translate.svn.sourceforge.net/viewvc/translate/src/trunk/translate/tools/phppo2pypo.py?view=markup">phppo2pypo</a> and <a href="http://translate.svn.sourceforge.net/viewvc/translate/src/trunk/translate/tools/pypo2phppo.py?view=markup">pypo2phppo</a> to convert between the two types.</p>
<p>Crisis averted, right?  Oh, that&#8217;s just scratching the surface.  Remember <a href="http://micropipes.com/blog/2008/07/09/adding-context-to-amo-po-files/">how happy I was that PHP finally started supporting msgctxt</a>?  Well, Python has had <a href="http://bugs.python.org/issue2504">a patch for it since 2008</a> but no one has bothered to land it.  I wrote a new <a href="http://github.com/clouserw/tower/blob/master/l10n/__init__.py">ugettext() and ungettext()</a> that recognizes context in the .po files.  To use simply do: <em>from l10n import ugettext as _</em> at the top of your file.</p>
<p>Along with adding msgctxt support, those two functions also collapse consecutive white space.  We&#8217;re using <a href="http://jinja.pocoo.org/2/">Jinja2</a> with <a href="http://babel.edgewall.org/">Babel</a> and the <a href="http://jinja.pocoo.org/2/documentation/extensions">i18n extension</a> as our template engine.  Jinja2 has a concept of stripping white space from the beginning or end of a string but does nothing about the middle.  A paragraph of text in a Jinja2 template would look like:<br />
<code><br />
  {% trans -%}Mozilla is providing links to these applications<br />
  as a courtesy, and makes no representations regarding the<br />
  applications or any information related thereto. Any questions,<br />
  complaints or claims regarding the applications must be<br />
  directed to the appropriate software vendor.<br />
  {%- endtrans %}<br />
</code></p>
<p>That&#8217;s a decent looking template, right?  Yeah, well, when Babel extracts that, it includes all the line breaks too, giving you something <a href="http://bitbucket.org/plurk/solace/src/tip/solace/i18n/messages.pot#cl-625">like this</a>.  The localizers would revolt if I sent them that, so I added in auto white-space collapsing.  Getting Babel to use the new functions means <a href="http://github.com/clouserw/tower/blob/master/tower/management/commands/extract.py">a new extraction script</a>.</p>
<p>At this point, we&#8217;re extracting strings from our new code and we can convert between Python and PHP files.  All we need now is a Frankenstein mix of xgettext functions to act as glue.  Meet the <a href="http://github.com/clouserw/tower/blob/master/l10n/management/commands/amalgamate.py">amalgamate script</a> that uses the pypo2php scripts, concatenates the .pot files, and merge updates each locales .po file.  After that it&#8217;s <a href="http://viewvc.svn.mozilla.org/vc?revision=63671&#038;view=revision">quick tweaks to the build scripts</a> to create z-messages.po files and we&#8217;re done.</p>
<p>So, all that said, the new process for L10n, while we&#8217;re in this transitional phase, is:</p>
<ol>
<li>From the PHP code, run <em>locale/extract-po-remora.sh</em>.  That pulls everything from all the PHP files, creates <em>locale/r-keys.pot</em>, updates the messages.po file for each locale, and compiles them.  Life used to be so simple.</li>
<li>From the python code, make sure you&#8217;re up to date, then run <em>./manage.py extract</em>.  That will pull everything from the python code and templates and create <em>locale/z-keys.pot</em>.</li>
<li>Run <em>./manage.py amalgamate</em>.  That will merge the z-keys.pot into the PHP messages.po files.</li>
<li>Localizers can make their changes as usual, and commit back to messages.po.</li>
<li>From PHP, <em>locale/copy-to-zamboni.py locale</em> will create z-messages.po files in the Python format. We could skip right to .mo files, but in case something goes wrong I want to see the .po files.</li>
<li>Then, like today, <em>locale/compile-mo.sh locale</em> will compile all the .po files.</li>
</ol>
<p>After all those steps are done, we&#8217;ve got duplicate .mo files, aside from formatting, and each application can look at its own .mo to get the strings it needs.  All this code is just a big band-aid and there are plenty of things that are more fun than juggling L10n between two applications across two <abbr title="Revision Control Systems">RCS</abbr>s.  But we knew what we were getting in to.  I&#8217;ll post something more positive later to help justify it. <img src='http://micropipes.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2010/03/08/maintaining-localization-between-python-and-php-its-not-fun/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Automating &#8220;Thinking of you&#8221;</title>
		<link>http://micropipes.com/blog/2009/07/20/automating-thinking-of-you/</link>
		<comments>http://micropipes.com/blog/2009/07/20/automating-thinking-of-you/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 17:53:39 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/?p=81</guid>
		<description><![CDATA[I had an idea a few weeks ago. I&#8217;ve got a bunch of great photos on my computer that no one ever sees unless we meet in person. Sure, we&#8217;ve got flickr and social networking sites, but I&#8217;m talking about an old photo that someone only saw once in passing, or a favorite shot from [...]]]></description>
			<content:encoded><![CDATA[<p>I had an idea a few weeks ago.  I&#8217;ve got a bunch of great photos on my computer that no one ever sees unless we meet in person.  Sure, we&#8217;ve got <a href="http://www.flickr.com/">flickr</a> and social networking sites, but I&#8217;m talking about an old photo that someone only saw once in passing, or a favorite shot from summer while you&#8217;re huddled over your heater wondering when the sun is coming back.</p>
<p>I can look at them any time, and there are a few on flickr that other people can look at, but what about people that aren&#8217;t tech savvy or are really busy and get caught up in the daily grind?</p>
<p>I was thinking, the answer can be a really simple script running from cron, say, weekly.  It picks a random photo from a directory and emails it to a group of people.  That&#8217;s it.  The idea is:</p>
<ul>
<li>it&#8217;s low tech compared to RSS feeds and social networking sites.  This &#8220;just works&#8221; with the tools people (potentially, low-tech people) are already used to using.</li>
<li>in a similar vein, commenting and discussion are built in if you feel like it.</li>
<li>it&#8217;s focused on the people on the CC list.  Sending out an old photo that is relevant just to those people has a lot more effect than one scrolling by on flickr.  It&#8217;s got a personal touch.</li>
<li>it&#8217;s automatic.  You wake up Monday morning, drag yourself to work, and there is a photo from 15 years ago in your inbox and you can laugh about how bad your hair was.  Awesome.</li>
</ul>
<p>So, I thought I would try it and cooked up <a href="http://svn.micropipes.com/audreytoo/audreytoo.py">audreytoo</a>.  Basically, you seed a directory with <em>copies</em> of the pictures you want to send out, add the script to a cron job, and it does it&#8217;s thing.  There are a couple other features in the script that you could look at if you want to get fancier.</p>
<p>I realize there is some irony in using an automated script to say &#8220;I&#8217;m thinking of you&#8221; but as long as I&#8217;m on the CC list it&#8217;s still true. <img src='http://micropipes.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   Anyway, I&#8217;m sharing the code in case anyone else can find value in it.</p>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2009/07/20/automating-thinking-of-you/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Planning your API is important</title>
		<link>http://micropipes.com/blog/2008/07/14/planning-your-api-is-important/</link>
		<comments>http://micropipes.com/blog/2008/07/14/planning-your-api-is-important/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 07:04:34 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/?p=55</guid>
		<description><![CDATA[I&#8217;m upgrading some code I wrote to talk to a new version of the Citrix NetScaler&#8216;s API. The NetScaler&#8217;s manuals (that&#8217;s right, plural) weigh in at a combined 1114 pages so documentation isn&#8217;t a problem and their implementation is a breeze using WSDL over SOAP. However, some of the core changes left me scratching my [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m upgrading some code I wrote to talk to a new version of the <a href="http://www.citrix.com/English/ps2/products/product.asp?contentID=21679">Citrix NetScaler</a>&#8216;s <abbr title="Application Programming Interface">API</abbr>.  The NetScaler&#8217;s manuals (that&#8217;s right, plural) weigh in at a combined 1114 pages so documentation isn&#8217;t a problem and their implementation is a breeze using <abbr title="Web Services Definition Language">WSDL</abbr> over <abbr title="Simple Object Access Protocol">SOAP</abbr>.  However, some of the core changes left me scratching my head.  Case in point:</p>
<p>To get an object out of the cache in the previous version the method signature was:</p>
<blockquote><p>getcacheobject(string $url, string $host, unsignedInt $port)</p></blockquote>
<p>$url in this case is what is commonly referred to as the &#8220;path&#8221; in a standard <abbr title="Uniform Resource Locator">URL</abbr>; e.g. /en-US/index.html.  That&#8217;s simple enough to use, let&#8217;s see what the new version has:</p>
<blockquote><p>getcacheobject(string $url, unsignedLong $locator, string $host, unsignedInt $port [...]</p></blockquote>
<p>$locator is an internal id for a cache object which is defintitely something I should be able to use to expire content, but what is it doing in the middle of my url+host pair?  The error messages are happy to let me know that I <b>can&#8217;t</b> pass both $url and $locator to the same call and if I pass $url I <b>must</b> pass $host.  That means I will always have be passing a null value in either the first or second parameter.</p>
<p>And if you&#8217;re thinking it&#8217;s for consistency with other methods, think again.  To flush an object we&#8217;ve got:</p>
<blockquote><p>flushcacheobject(unsignedLong $locator, string $url, string $host, unsignedInt $port [...]</p></blockquote>
<p>Moral of the story: planning and consistency makes happy programmers; particularly with an API.</p>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2008/07/14/planning-your-api-is-important/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>When is a TINYINT(1) not a TINYINT(1)?</title>
		<link>http://micropipes.com/blog/2008/03/07/when-is-a-tinyint1-not-a-tinyint1/</link>
		<comments>http://micropipes.com/blog/2008/03/07/when-is-a-tinyint1-not-a-tinyint1/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 23:50:30 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[o rly]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/2008/03/07/when-is-a-tinyint1-not-a-tinyint1/</guid>
		<description><![CDATA[When you&#8217;re using CakePHP! Turns out CakePHP considers a TINYINT(1) to be a Boolean. Judging from all the support tickets that have been filed, I&#8217;m not the first person to get taken off guard by this behavior. When I asked about it on IRC, the response was that since MySQL considers a TINYINT(1) to be [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re using <a href="http://cakephp.org/">CakePHP</a>!</p>
<p>Turns out CakePHP considers a TINYINT(1) to be a Boolean.  Judging from all <a href="https://trac.cakephp.org/ticket/1253">the</a> <a href="https://trac.cakephp.org/ticket/3903">support</a> <a href="https://trac.cakephp.org/ticket/4026">tickets</a> that have been filed, I&#8217;m not the first person to get taken off guard by this behavior.  When I asked about it on IRC, the response was that since MySQL considers a TINYINT(1) to be a Boolean, CakePHP does too.  That&#8217;s not true.</p>
<p>From the <a href="http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html">MySQL manual</a>:</p>
<blockquote><p>As of MySQL 5.0.3, a BIT data type is available for storing bit-field values. (Before 5.0.3, MySQL interprets BIT as TINYINT(1).)</p></blockquote>
<p>That&#8217;s saying if I request a BIT it will make it a TINYINT, not if I request a TINYINT it will make it a BIT.  Having a framework change the definitions of my database columns sounds crazy to me, but judging from <a href="https://trac.cakephp.org/ticket/1253">the ticket filed in 2006</a> this has been CakePHP&#8217;s policy for a long time.  Despite the long standing precedent I can&#8217;t find any documentation about it online other than the closing remarks of those support tickets.  </p>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2008/03/07/when-is-a-tinyint1-not-a-tinyint1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Frameworks that start sessions for every visitor make me sad</title>
		<link>http://micropipes.com/blog/2008/03/06/frameworks-that-start-sessions-for-every-visitor-make-me-sad/</link>
		<comments>http://micropipes.com/blog/2008/03/06/frameworks-that-start-sessions-for-every-visitor-make-me-sad/#comments</comments>
		<pubDate>Thu, 06 Mar 2008 07:00:48 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[AMO]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/2008/03/06/frameworks-that-start-sessions-for-every-visitor-make-me-sad/</guid>
		<description><![CDATA[I might have played the devil&#8217;s advocate when Lars was hating on frameworks at the barcamp last weekend, but that doesn&#8217;t mean I don&#8217;t see his point. The latest in a series of frustrations with frameworks kept me up until 3am last night. What better way to cap it off than complaining on the internet? [...]]]></description>
			<content:encoded><![CDATA[<p>I might have played the devil&#8217;s advocate when <a href="http://staff.osuosl.org/~lohnk/blog/">Lars</a> was hating on frameworks at the <a href="http://barcamp.org/BeaverBarCamp">barcamp</a> last weekend, but that doesn&#8217;t mean I don&#8217;t see his point.  The latest in a series of frustrations with frameworks kept me up until 3am last night.  What better way to cap it off than complaining on the internet?</p>
<p>Today&#8217;s subject is anonymous sessions.  Frameworks (and developers) love them because they are simple and convenient, but it comes at a cost.  Keeping track of sessions for every visitor on a high traffic site is far too expensive to be practical.  Developers should know how to work around this, but their frameworks need to support them.</p>
<p>The first framework on my mind is <a href="http://drupal.org/">Drupal</a>.  I filed <a href="http://drupal.org/node/201122">an issue</a> last year that Drupal should support disabling anonymous sessions.  It&#8217;s still unassigned so I&#8217;m guessing it&#8217;s not a high priority, but it was one of the main things that made me choose not to use Drupal on mozilla.com.  I <a href="http://drupal.org/node/183006">wrote some ideas</a> on how to handle it and got some responses from people suffering the same fate.  No word on any progress though.</p>
<p>The second framework, <a href="http://cakephp.org/">CakePHP</a>, has an AUTO_SESSION variable that, <a href="http://micropipes.com/blog/2008/01/07/cakephps-cache-that-wouldnt-quit/">just like $cacheQueries</a>, is far to easy to misplace faith in.</p>
<p>By setting AUTO_SESSION to false, you can&#8217;t read or write to the session.  Working as advertised?  Not so much.  If you take a closer look at what&#8217;s actually happening you&#8217;ll see that the session is still getting started, it&#8217;s just that CakePHP is blocking your access to it.  Even with AUTO_SESSION off, a cookie with a unique ID is set, and <strong>a row is still inserted into the sessions table</strong>.  That last part almost brought down <a href="https://addons.mozilla.org/">AMO</a> last night.  I wrote <a href="http://viewvc.svn.mozilla.org/vc/addons/trunk/site/cake/libs/controller/components/session.php?r1=10970&#038;r2=10969&#038;pathrev=10970">a patch that disables anonymous sessions for real</a>, but anyone that has talked to me about patching core code knows I don&#8217;t like to do it.</p>
<p>When you&#8217;re writing code, framework or not, don&#8217;t forget about scalability.</p>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2008/03/06/frameworks-that-start-sessions-for-every-visitor-make-me-sad/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The most worthless bot on IRC</title>
		<link>http://micropipes.com/blog/2008/01/02/the-most-worthless-bot-on-irc/</link>
		<comments>http://micropipes.com/blog/2008/01/02/the-most-worthless-bot-on-irc/#comments</comments>
		<pubDate>Thu, 03 Jan 2008 02:51:13 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/2008/01/02/the-most-worthless-bot-on-irc/</guid>
		<description><![CDATA[I&#8217;m not one to jump on bandwagons just because they&#8217;re rolling by (even with great companions), but I started using Python in one of my projects and I&#8217;ve got to say that I&#8217;m pretty happy with it. I think their documentation leaves something to be desired but overall the language is pretty intuitive and it [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not one to jump on bandwagons just because they&#8217;re rolling by (even with <a href="http://xkcd.com/353/">great companions</a>), but I <a href="http://svn.mozilla.org/projects/kubla/trunk/scripts/kublad.py">started using Python</a> in one of my projects and I&#8217;ve got to say that I&#8217;m pretty happy with it.  I think <a href="http://docs.python.org/">their documentation</a> leaves something to be desired but overall the language is pretty intuitive and it has enough of a following that libraries are plentiful.</p>
<p>One evening I decided I wanted to try making an <abbr title="Internet Relay Chat">IRC</abbr> bot (because you know we need more of those!).  I&#8217;d only worked with Python briefly before, but armed with the confidence only a language that you don&#8217;t know the shortcomings of can bring, I started writing code.  After less than an hour and about 85 well-spaced lines of code later, <a href="http://svn.micropipes.com/aaplsauce/trunk/aaplsauce.py">Aaplsauce</a> was born.  All it does is sit idle in a channel and watch for someone to say something about <a href="http://finance.google.com/finance?client=ob&#038;q=AAPL"><abbr title="Apple Inc.">AAPL</abbr></a>.  After someone mentions the magic phrase the bot looks up the price and prints it in the channel.  How convenient!</p>
<p>So, nearly worthless?  Absolutely.  But the code is short and easy to write and python made that possible.  <abbr title="&quot;Thanks.&quot;  That's right.  I abbr'd it.">Thx</abbr> Python.</p>
<p><em>(yeah, if you read the code there is one other command the bot understands and, no, there&#8217;s no auth on it.  Don&#8217;t make me do it! <img src='http://micropipes.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</em></p>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2008/01/02/the-most-worthless-bot-on-irc/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Threadbubble on AMO</title>
		<link>http://micropipes.com/blog/2007/07/11/threadbubble-on-amo/</link>
		<comments>http://micropipes.com/blog/2007/07/11/threadbubble-on-amo/#comments</comments>
		<pubDate>Wed, 11 Jul 2007 08:53:30 +0000</pubDate>
		<dc:creator>Wil Clouser</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[AMO]]></category>
		<category><![CDATA[ThreadBubble]]></category>
		<category><![CDATA[Thunderbird]]></category>

		<guid isPermaLink="false">http://micropipes.com/blog/2007/07/11/threadbubble-on-amo/</guid>
		<description><![CDATA[I submitted Threadbubble to AMO tonight. I wanted to work out the bugs and get it in a stable state before I put it on there and I think it&#8217;s reached that point. Hosting it on AMO will prevent potential security issues, and it has the side benefit of providing automatic updates. The add-on is [...]]]></description>
			<content:encoded><![CDATA[<p>I submitted Threadbubble to <a href="https://addons.mozilla.org/">AMO</a> tonight.  I wanted to work out the bugs and get it in a stable state before I put it on there and I think it&#8217;s reached that point.  Hosting it on AMO will prevent <a href="http://developer.mozilla.org/devnews/index.php/2007/05/30/add-on-updates/">potential security issues</a>, and it has the side benefit of providing automatic updates.</p>
<p>The <a href="https://addons.mozilla.org/en-US/thunderbird/addon/5326">add-on is available</a>, but it&#8217;s currently in the sandbox (which means you&#8217;ll have to login if you want to see it).  If you already have an account, feel free to add a review so I can get started on <a href="https://addons.mozilla.org/en-US/firefox/pages/policy">the process</a> to get onto the public side of AMO.</p>
<p>Once the add-on hits the public side, anyone with an older version will get automatically updated which should help anyone experiencing the &#8220;disappearing threads&#8221; from version 0.3.</p>
]]></content:encoded>
			<wfw:commentRss>http://micropipes.com/blog/2007/07/11/threadbubble-on-amo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
