<?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>chris' random ramblings &#187; Linux</title>
	<atom:link href="http://atlee.ca/blog/category/technology/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://atlee.ca/blog</link>
	<description>programming, photography, media, and anything else that strikes my fancy</description>
	<lastBuildDate>Tue, 11 May 2010 15:15:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>poster 0.6.0 released</title>
		<link>http://atlee.ca/blog/2010/05/10/poster-0-6-0-released/</link>
		<comments>http://atlee.ca/blog/2010/05/10/poster-0-6-0-released/#comments</comments>
		<pubDate>Tue, 11 May 2010 02:23:36 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[package]]></category>
		<category><![CDATA[poster]]></category>
		<category><![CDATA[utilities]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=740</guid>
		<description><![CDATA[I&#8217;ve just pushed poster 0.6.0 to the cheeseshop.
Thanks again to everybody who sent in bug reports, and for letting me know how you&#8217;re using poster!  It&#8217;s really great to hear from users.
poster 0.6.0 fixes a few problems with 0.5, most notably:

Documentation updates to clarify some common use cases.
Added a poster.version attribute.  Thanks to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just pushed poster 0.6.0 to the <a href="http://pypi.python.org/pypi/poster/0.6.0">cheeseshop</a>.</p>
<p>Thanks again to everybody who sent in bug reports, and for letting me know how you&#8217;re using poster!  It&#8217;s really great to hear from users.</p>
<p>poster 0.6.0 fixes a few problems with 0.5, most notably:</p>
<ul>
<li>Documentation updates to clarify some common use cases.</li>
<li>Added a poster.version attribute.  Thanks to <a href="http://jcalderone.livejournal.com/54911.html">JP!</a></li>
<li>Fix for unicode filenames. Thanks to Zed Shaw.</li>
<li>Handle StringIO file objects. Thanks to Christophe Combelles.</li>
</ul>
<p>poster 0.6.0 can be downloaded from the <a href="http://pypi.python.org/pypi/poster/0.6.0">cheeseshop</a>, or from <a href="http://atlee.ca/software/poster/dist/0.6.0/">my website</a>.  Documentation can be found at <a href="http://atlee.ca/software/poster/">http://atlee.ca/software/poster/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2010/05/10/poster-0-6-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>One useful script, a linux version</title>
		<link>http://atlee.ca/blog/2009/11/13/one-useful-script-a-linux-version/</link>
		<comments>http://atlee.ca/blog/2009/11/13/one-useful-script-a-linux-version/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 14:55:18 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=630</guid>
		<description><![CDATA[Johnathan posted links to 3 scripts he finds useful.  His sattap script looked handy, so I hacked it up for linux.  Run it to do a screen capture, and upload the image to a website you have ssh access into.  The link is printed out, and put into the clipboard.
Hope you find [...]]]></description>
			<content:encoded><![CDATA[<p>Johnathan posted links to <a href="http://blog.johnath.com/2009/11/11/three-stupid-scripts-i-find-useful/">3 scripts he finds useful</a>.  His sattap script looked handy, so I hacked it up for linux.  Run it to do a screen capture, and upload the image to a website you have ssh access into.  The link is printed out, and put into the clipboard.</p>
<p>Hope you find this useful!</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;"># sattap - Send a thing to a place</span>
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-e</span>
&nbsp;
<span style="color: #007800;">SCP_USER</span>=<span style="color: #ff0000;">'catlee'</span>
<span style="color: #007800;">SCP_HOST</span>=<span style="color: #ff0000;">'people.mozilla.org'</span>
<span style="color: #007800;">SCP_PATH</span>=<span style="color: #ff0000;">'~/public_html/sattap/'</span>
&nbsp;
<span style="color: #007800;">HTTP_URL</span>=<span style="color: #ff0000;">&quot;http://people.mozilla.org/~catlee/sattap/&quot;</span>
&nbsp;
<span style="color: #007800;">FILENAME</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> <span style="color: #000000; font-weight: bold;">|</span> md5sum <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">head</span> <span style="color: #660033;">-c</span> <span style="color: #000000;">8</span><span style="color: #000000; font-weight: bold;">`</span>.png
<span style="color: #007800;">FILEPATH</span>=<span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$FILENAME</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> Capturing...
import <span style="color: #007800;">$FILEPATH</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> Copying to <span style="color: #007800;">$SCP_HOST</span>
<span style="color: #c20cb9; font-weight: bold;">scp</span> <span style="color: #007800;">$FILEPATH</span> <span style="color: #800000;">${SCP_USER}</span><span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${SCP_HOST}</span>:<span style="color: #007800;">$SCP_PATH</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> Deleting <span style="color: #7a0874; font-weight: bold;">local</span> copy
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #007800;">$FILEPATH</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$HTTP_URL</span><span style="color: #007800;">$FILENAME</span> <span style="color: #000000; font-weight: bold;">|</span> xclip <span style="color: #660033;">-selection</span> clipboard
<span style="color: #7a0874; font-weight: bold;">echo</span> Your <span style="color: #c20cb9; font-weight: bold;">file</span> should be at <span style="color: #007800;">$HTTP_URL</span><span style="color: #007800;">$FILENAME</span>, <span style="color: #c20cb9; font-weight: bold;">which</span> is also <span style="color: #000000; font-weight: bold;">in</span> your paste buffer</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2009/11/13/one-useful-script-a-linux-version/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>poster 0.5 released</title>
		<link>http://atlee.ca/blog/2009/10/07/poster-0-5-released/</link>
		<comments>http://atlee.ca/blog/2009/10/07/poster-0-5-released/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 12:54:47 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[poster]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=555</guid>
		<description><![CDATA[I&#8217;ve just released version 0.5 of poster, the streaming http upload library for python.  It&#8217;s easy_installable or downloadable directly from the cheeseshop.
Thanks again to everybody who&#8217;s written in with bug fixes and suggestions!
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just released version 0.5 of <a href="http://atlee.ca/software/poster/">poster</a>, the streaming http upload library for python.  It&#8217;s easy_installable or downloadable directly from the <a href="http://pypi.python.org/pypi/poster/">cheeseshop</a>.</p>
<p>Thanks again to everybody who&#8217;s written in with bug fixes and suggestions!</p>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2009/10/07/poster-0-5-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Profiling Buildbot</title>
		<link>http://atlee.ca/blog/2009/07/28/profiling-buildbot/</link>
		<comments>http://atlee.ca/blog/2009/07/28/profiling-buildbot/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 16:13:12 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[buildbot]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=450</guid>
		<description><![CDATA[Buildbot is a critical part of our build infrastructure at Mozilla.  We use it to manage builds on 5 different platforms (Linux, Mac, Windows, Maemo and Windows Mobile), and 5 different branches (mozilla-1.9.1, mozilla-central, TraceMonkey, Electrolysis, and Places).  All in all we have 80 machines doing builds across 150 different build types (not [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://buildbot.net">Buildbot</a> is a critical part of our build infrastructure at Mozilla.  We use it to manage builds on 5 different platforms (Linux, Mac, Windows, Maemo and Windows Mobile), and 5 different branches (mozilla-1.9.1, mozilla-central, TraceMonkey, Electrolysis, and Places).  All in all we have 80 machines doing builds across 150 different build types (not counting Talos; all the Talos test runs and slaves are managed by a different master).</p>
<p>And buildbot is at the center of it all.</p>
<p>The load on our machine running buildbot is normally fairly high, and occasionally spikes so that the buildbot process is unresponsive.  It normally restores itself within a few minutes, but I&#8217;d really like to know why it&#8217;s doing this!</p>
<p>Running our staging buildbot master with python&#8217;s <a href="http://docs.python.org/library/profile.html#module-cProfile">cProfile</a> module for almost two hours yields the following profile:</p>
<pre>
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   416377 4771.188    0.011 4796.749    0.012 {select.select}
       52  526.891   10.133  651.043   12.520 /tools/buildbot/lib/python2.5/site-packages/buildbot-0.7.10p1-py2.5.egg/buildbot/status/web/waterfall.py:834(phase2)
     6518  355.370    0.055  355.370    0.055 {posix.fsync}
   232582  238.943    0.001 1112.039    0.005 /tools/twisted-8.0.1/lib/python2.5/site-packages/twisted/spread/banana.py:150(dataReceived)
 10089681  104.395    0.000  130.089    0.000 /tools/twisted-8.0.1/lib/python2.5/site-packages/twisted/spread/banana.py:36(b1282int)
36798140/36797962   83.536    0.000   83.537    0.000 {len}
 29913653   70.458    0.000   70.458    0.000 {method 'append' of 'list' objects}
      311   63.775    0.205   63.775    0.205 {bz2.compress}
 10088987   56.581    0.000  665.982    0.000 /tools/twisted-8.0.1/lib/python2.5/site-packages/twisted/spread/banana.py:141(gotItem)
4010792/1014652   56.079    0.000  176.693    0.000 /tools/twisted-8.0.1/lib/python2.5/site-packages/twisted/spread/jelly.py:639(unjelly)
2343910/512709   47.954    0.000  112.446    0.000 /tools/twisted-8.0.1/lib/python2.5/site-packages/twisted/spread/banana.py:281(_encode)
</pre>
<h1>Interpreting the results</h1>
<p><code>select</code> shows up in the profile because we&#8217;re profiling wall clock time, not cpu time.  So the more time we&#8217;re spending in <code>select</code>, the better, since that means we&#8217;re just waiting for data.  The overall run time for this profile was 7,532 seconds, so <code>select</code> is taking around 63% of our total time.  I believe the more time spent here, the better.  Time spent inside <code>select</code> is idle time.</p>
<p>We already knew that the buildbot waterfall was slow (the second line in profile).</p>
<p><code>fsync</code> isn&#8217;t too surprising either.  buildbot calls <code>fsync</code> after writing log files to disk.  We&#8217;ve considered removing this call, and this profile lends support to our original guess.</p>
<p>The next entries really surprised me, twisted&#8217;s <code>dataReceived</code> and a decoding function, <code>b1282int</code>.  These are called when processing data received from the slaves.  If I&#8217;m reading this correctly, this means that <code>dataReceived</code> and children account for around 40% of our total time after you remove the time spent in <code>select</code>.  <code>1112 / (7532-4796) = 40%</code>.</p>
<p>These results are from our staging buildbot master, which doesn&#8217;t have anywhere near the same load as the production buildbot master.  I would expect that the time spent waiting in <code>select</code> would go down on the production master (there&#8217;s more data being received, more often), and that time spent in <code>fsync</code> and <code>dataReceived</code> would go up.</p>
<h1>What to do about it?</h1>
<p>A few ideas&#8230;.</p>
<ul>
<li>Use <a href="http://psyco.sourceforge.net/">psyco</a> to get some JIT goodness applied to some of the slower python functions.</li>
<li>Remove the <code>fsync</code> call after saving logs.</li>
<li>Use the cpu-time to profile rather than wallclock time.  This will give a different perspective on the performance of buildbot, which should give better information about where we&#8217;re spending time processing data.</li>
<li>Implement slow pieces in C (or cython).  Twisted&#8217;s Banana library looks do-able in C, and also is high up in the profile.</li>
<li>Send less data from the slaves.  We&#8217;re currently logging all stdout/stderr produced by the slaves.  All of this data is processed by the master process and then saved to disk.</li>
<li>Rearchitect buildbot to handle this kind of load.</li>
<li>Have more than one buildbot master, each one handling fewer slaves.  We&#8217;re actively looking into this approach, since it also allows us to have some redundancy for this critical piece of our infrastructure.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2009/07/28/profiling-buildbot/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>poster 0.4 released</title>
		<link>http://atlee.ca/blog/2009/04/05/poster-04-released/</link>
		<comments>http://atlee.ca/blog/2009/04/05/poster-04-released/#comments</comments>
		<pubDate>Sun, 05 Apr 2009 19:23:53 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[My Software]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[poster]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=365</guid>
		<description><![CDATA[I&#8217;m happy to announce the release of poster version 0.4.
This is a bug fix release, which fixes problems when trying to use poster over a secure connection (with https).
I&#8217;ve also reworked some of the code so that it can hopefully work with python 2.4.  It passes all the unit tests that I have under [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce the release of <a href="http://atlee.ca/software/poster">poster</a> version 0.4.</p>
<p>This is a bug fix release, which fixes problems when trying to use poster over a secure connection (with https).</p>
<p>I&#8217;ve also reworked some of the code so that it can hopefully work with python 2.4.  It passes all the unit tests that I have under python 2.4 now, but since I don&#8217;t normally use python 2.4, I&#8217;d be interested to hear other people&#8217;s experience using it.</p>
<p>One of the things that I love about working on poster, and about open source software in general, is hearing from users all over the world who have found it helpful in some way.  It&#8217;s always encouraging to hear about how poster is being used, so thank you to all who have e-mailed me!</p>
<p>poster can be downloaded from my <a href="http://atlee.ca/software/poster/dist/0.4/">website</a>, or from the <a href="http://pypi.python.org/pypi/poster/0.4">cheeseshop</a>. </p>
<p>As always, bug reports, comments, and questions are always welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2009/04/05/poster-04-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ssh on-the-fly port forwarding</title>
		<link>http://atlee.ca/blog/2008/12/09/ssh-on-the-fly-port-forwarding/</link>
		<comments>http://atlee.ca/blog/2008/12/09/ssh-on-the-fly-port-forwarding/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 02:35:54 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=248</guid>
		<description><![CDATA[Check out this great tip from nion&#8217;s blog:
ssh on-the-fly port forwarding.
I&#8217;ve often wanted to open up new port forwards, but haven&#8217;t wanted to shut down my existing session.

If you follow this by # character (and thus type ~#) you get a list of all forwarded connections.
Using ~C you can open an internal ssh shell that [...]]]></description>
			<content:encoded><![CDATA[<p>Check out this great tip from nion&#8217;s blog:</p>
<p><a href="http://nion.modprobe.de/blog/archives/656-guid.html">ssh on-the-fly port forwarding</a>.</p>
<p>I&#8217;ve often wanted to open up new port forwards, but haven&#8217;t wanted to shut down my existing session.</p>
<blockquote><p>
If you follow this by # character (and thus type ~#) you get a list of all forwarded connections.<br />
Using ~C you can open an internal ssh shell that enables you to add and remove local/remote port forwardings</p>
<p>ssh> help<br />
Commands:<br />
  -L[bind_address:]port:host:hostport Request local forward<br />
  -R[bind_address:]port:host:hostport Request remote forward<br />
  -KR[bind_address:]port Cancel remote forward</p>
<p>ssh> -L 8080:localhost:8080
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2008/12/09/ssh-on-the-fly-port-forwarding/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>poster 0.2 is out</title>
		<link>http://atlee.ca/blog/2008/12/05/poster-02-is-out/</link>
		<comments>http://atlee.ca/blog/2008/12/05/poster-02-is-out/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 15:36:28 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[poster]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=234</guid>
		<description><![CDATA[I&#8217;ve fixed a few bugs with poster, and released the next version, 0.2.  It&#8217;s available from the cheeseshop, or from my web page.
Documentation can also be found here.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve fixed a few bugs with <a href="http://atlee.ca/software/poster">poster</a>, and released the next version, 0.2.  It&#8217;s available from the <a href="http://pypi.python.org/pypi/poster/0.2">cheeseshop</a>, or from my <a href="http://atlee.ca/software/poster/dist/0.2/">web page</a>.</p>
<p>Documentation can also be found <a href="http://atlee.ca/software/poster">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2008/12/05/poster-02-is-out/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>python reload: danger, here be dragons</title>
		<link>http://atlee.ca/blog/2008/11/21/python-reload-danger-here-be-dragons/</link>
		<comments>http://atlee.ca/blog/2008/11/21/python-reload-danger-here-be-dragons/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 15:26:40 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[buildbot]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[reload]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=211</guid>
		<description><![CDATA[At Mozilla, we use buildbot to coordinate performing builds, unit tests, performance tests, and l10n repacks across all of our build slaves.
There is a lot of activity on a project the size of Firefox, which means that the build slaves are kept pretty busy most of the time.
Unfortunately, like most software out there, our buildbot [...]]]></description>
			<content:encoded><![CDATA[<p>At <a href="http://mozilla.com">Mozilla</a>, we use <a href="http://buildbot.net">buildbot</a> to coordinate performing builds, unit tests, performance tests, and l10n repacks across all of our build slaves.</p>
<p>There is a lot of activity on a project the size of Firefox, which means that the build slaves are kept pretty busy most of the time.</p>
<p>Unfortunately, like most software out there, our buildbot code has bugs in it.  buildbot provides two ways of picking up new changes to code and configuration: &#8216;buildbot restart&#8217; and &#8216;buildbot reconfig&#8217;.</p>
<p>Restarting buildbot is the cleanest thing to do: it shuts down the existing buildbot process, and starts a new one once the original has shut down cleanly.  The problem with restarting is that it interrupts any builds that are currently active.</p>
<p>The second option, &#8216;reconfig&#8217;, is usually a great way to pick up changes to buildbot code without interrupting existing builds.  &#8216;reconfig&#8217; is implemented by sending SIGHUP to the buildbot process, which triggers a python <a href="http://docs.python.org/library/functions.html#reload">reload()</a> of certain files.</p>
<p>This is where the problem starts.</p>
<p>Reloading a module basically re-initializes the module, including redefining any classes that are in the module&#8230;which is what you want, right?  The whole reason you&#8217;re reloading is to pick up changes to the code you have in the module!</p>
<p>So let&#8217;s say you have a module, foo.py, with these classes:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Foo<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Foo.foo&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Bar<span style="color: black;">&#40;</span>Foo<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Bar.foo&quot;</span>
        Foo.<span style="color: black;">foo</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span></pre></div></div>

<p>and you&#8217;re using it like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> foo
<span style="color: #66cc66;">&gt;&gt;&gt;</span> b = foo.<span style="color: black;">Bar</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> b.<span style="color: black;">foo</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
Bar.<span style="color: black;">foo</span>
Foo.<span style="color: black;">foo</span></pre></div></div>

<p>Looks good!  Now, let&#8217;s do a reload, which is what buildbot does on a &#8216;reconfig&#8217;:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">reload</span><span style="color: black;">&#40;</span>foo<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>module <span style="color: #483d8b;">'foo'</span> <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #483d8b;">'foo.pyc'</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> b.<span style="color: black;">foo</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
Bar.<span style="color: black;">foo</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #ff4500;">1</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
  File <span style="color: #483d8b;">&quot;/Users/catlee/test/foo.py&quot;</span>, line <span style="color: #ff4500;">13</span>, <span style="color: #ff7700;font-weight:bold;">in</span> foo
    Foo.<span style="color: black;">foo</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: unbound method foo<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> must be called <span style="color: #ff7700;font-weight:bold;">with</span> Foo instance <span style="color: #ff7700;font-weight:bold;">as</span> first argument <span style="color: black;">&#40;</span>got Bar instance instead<span style="color: black;">&#41;</span></pre></div></div>

<p>Whoops!  What happened?  The TypeError exception is complaining that Foo.foo must be called with an instance of Foo as the first argument.  <em>(NB: we&#8217;re calling the unbound method on the class here, not a bound method on the instance, which is why we need to pass in &#8217;self&#8217; as the first argument.  This is typical when calling your parent class)</em></p>
<p>But wait!  Isn&#8217;t Bar a sub-class of Foo?  And why did this work before?  Let&#8217;s try this again, but let&#8217;s watch what happens to Foo and Bar this time, using the <a href="http://docs.python.org/library/functions.html#id">id()</a> function:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> foo
<span style="color: #66cc66;">&gt;&gt;&gt;</span> b = foo.<span style="color: black;">Bar</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">id</span><span style="color: black;">&#40;</span>foo.<span style="color: black;">Bar</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3217664</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">reload</span><span style="color: black;">&#40;</span>foo<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>module <span style="color: #483d8b;">'foo'</span> <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #483d8b;">'foo.pyc'</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">id</span><span style="color: black;">&#40;</span>foo.<span style="color: black;">Bar</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3218592</span></pre></div></div>

<p><em>(The <a href="http://docs.python.org/library/functions.html#id">id()</a> function returns a unique identifier for objects in python; if two objects have the same id, then they refer to the same object)</em></p>
<p>The id&#8217;s are different, which means that we get a new Bar class after we reload&#8230;I guess that makes sense.  Take a look at our b object, which was created before the reload:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> b.__class__
<span style="color: #66cc66;">&lt;</span>class <span style="color: #483d8b;">'foo.Bar'</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">id</span><span style="color: black;">&#40;</span>b.__class__<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3217664</span></pre></div></div>

<p>So b is an instance of the <em>old</em> Bar class, not the new one.  Let&#8217;s look deeper:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> b.__class__.__bases__
<span style="color: black;">&#40;</span><span style="color: #66cc66;">&lt;</span>class <span style="color: #483d8b;">'foo.Foo'</span><span style="color: #66cc66;">&gt;</span>,<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">id</span><span style="color: black;">&#40;</span>b.__class__.__bases__<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3216336</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">id</span><span style="color: black;">&#40;</span>foo.<span style="color: black;">Foo</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3218128</span></pre></div></div>

<p>A ha!  The old Bar&#8217;s base class (Foo) is different than what&#8217;s currently defined in the module.  After we reloaded the foo module, the Foo class was redefined, which is presumably what we want.  The unfortunate side effect of this is that any references by name to the class &#8216;Foo&#8217; will pick up the new Foo class, including <strong>code in methods of subclasses</strong>.  There are probably other places where this has unexpected results, but for us, this is the biggest problem.</p>
<p>Reloading essentially breaks class inheritance for objects whose lifetime spans the reload.  Using <a href="http://docs.python.org/library/functions.html#super">super()</a> in the normal way doesn&#8217;t even work, since you usually refer to your instance&#8217;s class by name:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Bar<span style="color: black;">&#40;</span>Foo<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Bar.foo&quot;</span>
        <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>Bar, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">foo</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>If you&#8217;re using new-style classes, it looks like you can get around this by looking at your __class__ attribute:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Bar<span style="color: black;">&#40;</span>Foo<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Bar.foo&quot;</span>
        <span style="color: #008000;">super</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.__class__, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">foo</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Buildbot isn&#8217;t using new-style classes&#8230;yet&#8230;so we can&#8217;t use super().  Another workaround I&#8217;m playing around with is to use the inspect module to get at the class hierarchy:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> get_parent<span style="color: black;">&#40;</span>obj, n=<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">inspect</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">inspect</span>.<span style="color: black;">getmro</span><span style="color: black;">&#40;</span>obj.__class__<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>n<span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Bar<span style="color: black;">&#40;</span>Foo<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Bar.foo&quot;</span>
        get_parent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">foo</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2008/11/21/python-reload-danger-here-be-dragons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When craziness wraps around&#8230; : technovelty</title>
		<link>http://atlee.ca/blog/2008/11/12/when-craziness-wraps-around-technovelty/</link>
		<comments>http://atlee.ca/blog/2008/11/12/when-craziness-wraps-around-technovelty/#comments</comments>
		<pubDate>Wed, 12 Nov 2008 14:14:20 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=206</guid>
		<description><![CDATA[From When craziness wraps around&#8230;:
A common trick years ago was to set up your routing tables and then have PID 1 exit so the kernel paniced, because the paniced kernel would continue to route packets with _no_userspace_running_. Darn hard to hack a system like that.
That&#8217;s awesome    Better get your routing tables right [...]]]></description>
			<content:encoded><![CDATA[<p>From <a href="http://www.technovelty.org/humor/when-crazy-wraps.html">When craziness wraps around&#8230;</a>:</p>
<blockquote><p>A common trick years ago was to set up your routing tables and then have PID 1 exit so the kernel paniced, because the paniced kernel would continue to route packets with _no_userspace_running_. Darn hard to hack a system like that.</p></blockquote>
<p>That&#8217;s awesome <img src='http://atlee.ca/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   Better get your routing tables right the first time though!</p>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2008/11/12/when-craziness-wraps-around-technovelty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrading Wordpress with Mercurial</title>
		<link>http://atlee.ca/blog/2008/10/25/upgrading-wordpress-with-mercurial/</link>
		<comments>http://atlee.ca/blog/2008/10/25/upgrading-wordpress-with-mercurial/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 02:36:00 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=179</guid>
		<description><![CDATA[Since Mozilla has started using Mercurial for source control, I thought I shoud get some hands on experience with it.
My Wordpress dashboard has been nagging me to upgrade to the latest version for quite a while now.  I was running 2.5.1 up until today, which was released back in April.  I&#8217;ve been putting [...]]]></description>
			<content:encoded><![CDATA[<p>Since <a href="http://mozilla.com">Mozilla</a> has started using <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a> for source control, I thought I shoud get some hands on experience with it.</p>
<p>My <a href="http://wordpress.org">Wordpress</a> dashboard has been nagging me to upgrade to the latest version for quite a while now.  I was running 2.5.1 up until today, which was released back in April.  I&#8217;ve been putting off upgrading because it&#8217;s always such a pain if you follow the recommended instructions, and I inevitably end up forgetting to migrate some customization I made to the old version.</p>
<p>So, to kill two birds with one stone, I decided to try my hand at upgrading Wordpress by using Mercurial to track my changes to the default install, as well as the changes between versions of Wordpress.</p>
<p><strong>Preparation:</strong><br />
First, start off with a copy of my blog&#8217;s code in a directory called &#8216;blog&#8217;.<br />
Download Wordpress 2.5.1 and 2.6.3 (the version I want to upgrade to).</p>
<p><strong>Import initial Wordpress code:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">tar</span> zxf wordpress-2.5.1.tar.gz <span style="color: #666666; font-style: italic;"># NB: unpacks into wordpress/</span>
<span style="color: #c20cb9; font-weight: bold;">mv</span> wordpress wordpress-2.5.1
<span style="color: #7a0874; font-weight: bold;">cd</span> wordpress-2.5.1
hg init
hg commit <span style="color: #660033;">-A</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">'wordpress 2.5.1'</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> ..</pre></div></div>

<p><strong>Apply my changes:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">hg clone wordpress-2.5.1 wordpress-mine
<span style="color: #7a0874; font-weight: bold;">cd</span> wordpress-mine
hg qnew <span style="color: #660033;">-m</span> <span style="color: #ff0000;">'my blog'</span> my-blog.patch
hg <span style="color: #c20cb9; font-weight: bold;">locate</span> <span style="color: #660033;">-0</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #660033;">-0</span> <span style="color: #c20cb9; font-weight: bold;">rm</span>
<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-ar</span> ..<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/*</span> .
hg addremove
hg qrefresh
<span style="color: #7a0874; font-weight: bold;">cd</span> ..</pre></div></div>

<p>The &#8216;hg locate -0&#8242; line removes all the files currently tracked by Mercurial.  This is needed so that any files I deleted from my copy of Wordpress also are deleted in my Mercurial repository.</p>
<p>The result of these two steps is that I have a repository that has the original Wordpress source code as one revision, with my changes applied as a <a href="http://hgbook.red-bean.com/hgbookch12.html">Mercurial Queue</a> patch.</p>
<p>Now I need to tell Mercurial what&#8217;s changed between versions 2.5.1 and 2.6.3.  To do this, I&#8217;ll make a copy (or clone) of the 2.5.1 repository, and then put all the 2.6.3 files into it.  Again, I use &#8216;hg locate -0 | xargs -0 rm&#8217; to delete all the files from the old version before copying the new files in.  Mercurial is smart enough to notice if files haven&#8217;t changed, and the subsequent commit with the &#8216;-A&#8217; flag will add any new files or delete any files that were removed between 2.5.1 and 2.6.3.</p>
<p><strong>Upgrade the pristine 2.5.1 to 2.6.3:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">hg clone wordpress-2.5.1 wordpress-2.6.3
<span style="color: #c20cb9; font-weight: bold;">tar</span> zxf wordpress-2.6.3 <span style="color: #666666; font-style: italic;"># NB: Unpacks into wordpress/</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> wordpress-2.6.3
hg <span style="color: #c20cb9; font-weight: bold;">locate</span> <span style="color: #660033;">-0</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #660033;">-0</span> <span style="color: #c20cb9; font-weight: bold;">rm</span>
<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-ar</span> ..<span style="color: #000000; font-weight: bold;">/</span>wordpress<span style="color: #000000; font-weight: bold;">/*</span> .
hg commit <span style="color: #660033;">-A</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">'wordpress-2.6.3'</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> ..</pre></div></div>

<p>Now I need to perform the actual upgrade to my blog.  First I save the state of the current modifications, then pull in the 2.5.1 -> 2.6.3 changes from the wordpress-2.6.3 repository.  Then I reapply my changes to the new 2.6.3 code.</p>
<p><strong>Pull in 2.6.3 to my blog:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> wordpress-mine
hg qsave <span style="color: #660033;">-e</span> <span style="color: #660033;">-c</span>
hg pull ..<span style="color: #000000; font-weight: bold;">/</span>wordpress-2.6.3
hg update <span style="color: #660033;">-C</span>
hg qpush <span style="color: #660033;">-a</span> <span style="color: #660033;">-m</span></pre></div></div>

<p>Voilà!  A quick rsync to my website, and the upgrade is complete!</p>
<p>I have to admit, I don&#8217;t fully grok some of these Mercurial commands.  It took a few tries to work out this series of steps, so there&#8217;s probably a better way of doing it.  I&#8217;m pretty happy overall though; I managed a successful Wordpress upgrade, and learned something about Mercurial in the process!  The next upgrade should go much more smoothly now that I&#8217;ve figured things out a bit better.</p>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2008/10/25/upgrading-wordpress-with-mercurial/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
