<?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>Fri, 27 Jan 2012 19:08:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Investigating hg performance</title>
		<link>http://atlee.ca/blog/2011/12/09/hg-performance/</link>
		<comments>http://atlee.ca/blog/2011/12/09/hg-performance/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 07:02:28 +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[performance]]></category>

		<guid isPermaLink="false">http://atlee.ca/blog/?p=1035</guid>
		<description><![CDATA[(caveat lector: this is a long post with lots of shell snippets and output; it&#8217;s mostly a brain dump of what I did to investigate performance issues on hg.mozilla.org. I hope you find it useful. Scroll to the bottom for the summary.) Everybody knows that pushing to try can be slow. but why? while waiting [...]]]></description>
			<content:encoded><![CDATA[<p><em>(caveat lector: this is a long post with lots of shell snippets and output; it&#8217;s mostly a brain dump of what I did to investigate performance issues on hg.mozilla.org. I hope you find it useful. Scroll to the bottom for the summary.)</em></p>
<p><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=656757">Everybody</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=676420">knows</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=554656">that</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=708632">pushing</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=688240">to</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=695454">try</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=696682">can</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=672231">be</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=633161">slow</a>. but why?</p>
<p>while waiting for my push to try to complete, I wondered what exactly was slow.</p>
<p>I started by cloning my own version of try:</p>
<pre>
$ hg clone http://hg.mozilla.org try
destination directory: try
requesting all changes
adding changesets
adding manifests
adding file changes
added 95917 changesets with 447521 changes to 89564 files (+2446 heads)
updating to branch default
53650 files updated, 0 files merged, 0 files removed, 0 files unresolved
</pre>
<p>Next I instrumented hg so I could get some profile information:</p>
<pre>
$ sudo vi /usr/local/bin/hg
python -m cProfile -o /tmp/hg.profile /usr/bin/hg $*
</pre>
<p>Then I timed out long it took me to check what would be pushed:</p>
<pre>
$ time hg out ssh://localhost//home/catlee/mozilla/try
hg out ssh://localhost//home/catlee/mozilla/try  0.57s user 0.04s system 54% cpu 1.114 total
</pre>
<p>That&#8217;s not too bad. Let&#8217;s check our profile:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">pstats</span>
<span style="color: #dc143c;">pstats</span>.<span style="color: black;">Stats</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/tmp/hg.profile&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">strip_dirs</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">sort_stats</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'time'</span><span style="color: black;">&#41;</span>.<span style="color: black;">print_stats</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
Fri Dec  <span style="color: #ff4500;">9</span> 00:<span style="color: #ff4500;">25</span>:02 <span style="color: #ff4500;">2011</span>    /tmp/hg.<span style="color: #dc143c;">profile</span>
&nbsp;
         <span style="color: #ff4500;">38744</span> function calls <span style="color: black;">&#40;</span><span style="color: #ff4500;">37761</span> primitive calls<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #ff4500;">0.593</span> seconds
&nbsp;
   Ordered by: internal <span style="color: #dc143c;">time</span>
   List reduced <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #ff4500;">476</span> to <span style="color: #ff4500;">10</span> due to restriction <span style="color: #66cc66;">&lt;</span><span style="color: #ff4500;">10</span><span style="color: #66cc66;">&gt;</span>
&nbsp;
   ncalls  tottime  percall  cumtime  percall filename:lineno<span style="color: black;">&#40;</span>function<span style="color: black;">&#41;</span>
       <span style="color: #ff4500;">13</span>    <span style="color: #ff4500;">0.462</span>    <span style="color: #ff4500;">0.036</span>    <span style="color: #ff4500;">0.462</span>    <span style="color: #ff4500;">0.036</span> <span style="color: black;">&#123;</span>method <span style="color: #483d8b;">'readline'</span> of <span style="color: #483d8b;">'file'</span> objects<span style="color: black;">&#125;</span>
        <span style="color: #ff4500;">1</span>    <span style="color: #ff4500;">0.039</span>    <span style="color: #ff4500;">0.039</span>    <span style="color: #ff4500;">0.039</span>    <span style="color: #ff4500;">0.039</span> <span style="color: black;">&#123;</span>mercurial.<span style="color: black;">parsers</span>.<span style="color: black;">parse_index2</span><span style="color: black;">&#125;</span>
       <span style="color: #ff4500;">40</span>    <span style="color: #ff4500;">0.031</span>    <span style="color: #ff4500;">0.001</span>    <span style="color: #ff4500;">0.031</span>    <span style="color: #ff4500;">0.001</span> revlog.<span style="color: black;">py</span>:<span style="color: #ff4500;">291</span><span style="color: black;">&#40;</span>rev<span style="color: black;">&#41;</span>
        <span style="color: #ff4500;">1</span>    <span style="color: #ff4500;">0.019</span>    <span style="color: #ff4500;">0.019</span>    <span style="color: #ff4500;">0.019</span>    <span style="color: #ff4500;">0.019</span> revlog.<span style="color: black;">py</span>:<span style="color: #ff4500;">622</span><span style="color: black;">&#40;</span>headrevs<span style="color: black;">&#41;</span>
   <span style="color: #ff4500;">177</span>/<span style="color: #ff4500;">70</span>    <span style="color: #ff4500;">0.009</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.019</span>    <span style="color: #ff4500;">0.000</span> <span style="color: black;">&#123;</span><span style="color: #008000;">__import__</span><span style="color: black;">&#125;</span>
     <span style="color: #ff4500;">6326</span>    <span style="color: #ff4500;">0.004</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.006</span>    <span style="color: #ff4500;">0.000</span> cmdutil.<span style="color: black;">py</span>:<span style="color: #ff4500;">15</span><span style="color: black;">&#40;</span>parsealiases<span style="color: black;">&#41;</span>
       <span style="color: #ff4500;">13</span>    <span style="color: #ff4500;">0.003</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.003</span>    <span style="color: #ff4500;">0.000</span> <span style="color: black;">&#123;</span>method <span style="color: #483d8b;">'read'</span> of <span style="color: #483d8b;">'file'</span> objects<span style="color: black;">&#125;</span>
       <span style="color: #ff4500;">93</span>    <span style="color: #ff4500;">0.002</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.008</span>    <span style="color: #ff4500;">0.000</span> cmdutil.<span style="color: black;">py</span>:<span style="color: #ff4500;">18</span><span style="color: black;">&#40;</span>findpossible<span style="color: black;">&#41;</span>
     <span style="color: #ff4500;">7212</span>    <span style="color: #ff4500;">0.001</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.001</span>    <span style="color: #ff4500;">0.000</span> <span style="color: black;">&#123;</span>method <span style="color: #483d8b;">'split'</span> of <span style="color: #483d8b;">'str'</span> objects<span style="color: black;">&#125;</span>
  <span style="color: #ff4500;">392</span>/<span style="color: #ff4500;">313</span>    <span style="color: #ff4500;">0.001</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.007</span>    <span style="color: #ff4500;">0.000</span> demandimport.<span style="color: black;">py</span>:<span style="color: #ff4500;">92</span><span style="color: black;">&#40;</span>_demandimport<span style="color: black;">&#41;</span></pre></div></div>

<p>The top item is readline() on file objects? I wonder if that&#8217;s socket operations. I&#8217;m ssh&#8217;ing to localhost, so it&#8217;s really fast. Let&#8217;s add 100ms latency:</p>
<pre>
$ sudo tc qdisc add dev lo root handle 1:0 netem delay 100ms
$ time hg out ssh://localhost//home/catlee/mozilla/try
hg out ssh://localhost//home/catlee/mozilla/try  0.58s user 0.05s system 14% cpu 4.339 total
</pre>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">pstats</span>
<span style="color: #dc143c;">pstats</span>.<span style="color: black;">Stats</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/tmp/hg.profile&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">strip_dirs</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">sort_stats</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'time'</span><span style="color: black;">&#41;</span>.<span style="color: black;">print_stats</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
Fri Dec  <span style="color: #ff4500;">9</span> 00:<span style="color: #ff4500;">42</span>:09 <span style="color: #ff4500;">2011</span>    /tmp/hg.<span style="color: #dc143c;">profile</span>
&nbsp;
         <span style="color: #ff4500;">38744</span> function calls <span style="color: black;">&#40;</span><span style="color: #ff4500;">37761</span> primitive calls<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #ff4500;">2.728</span> seconds
&nbsp;
   Ordered by: internal <span style="color: #dc143c;">time</span>
   List reduced <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #ff4500;">476</span> to <span style="color: #ff4500;">10</span> due to restriction <span style="color: #66cc66;">&lt;</span><span style="color: #ff4500;">10</span><span style="color: #66cc66;">&gt;</span>
&nbsp;
   ncalls  tottime  percall  cumtime  percall filename:lineno<span style="color: black;">&#40;</span>function<span style="color: black;">&#41;</span>
       <span style="color: #ff4500;">13</span>    <span style="color: #ff4500;">2.583</span>    <span style="color: #ff4500;">0.199</span>    <span style="color: #ff4500;">2.583</span>    <span style="color: #ff4500;">0.199</span> <span style="color: black;">&#123;</span>method <span style="color: #483d8b;">'readline'</span> of <span style="color: #483d8b;">'file'</span> objects<span style="color: black;">&#125;</span>
        <span style="color: #ff4500;">1</span>    <span style="color: #ff4500;">0.054</span>    <span style="color: #ff4500;">0.054</span>    <span style="color: #ff4500;">0.054</span>    <span style="color: #ff4500;">0.054</span> <span style="color: black;">&#123;</span>mercurial.<span style="color: black;">parsers</span>.<span style="color: black;">parse_index2</span><span style="color: black;">&#125;</span>
       <span style="color: #ff4500;">40</span>    <span style="color: #ff4500;">0.028</span>    <span style="color: #ff4500;">0.001</span>    <span style="color: #ff4500;">0.028</span>    <span style="color: #ff4500;">0.001</span> revlog.<span style="color: black;">py</span>:<span style="color: #ff4500;">291</span><span style="color: black;">&#40;</span>rev<span style="color: black;">&#41;</span>
        <span style="color: #ff4500;">1</span>    <span style="color: #ff4500;">0.019</span>    <span style="color: #ff4500;">0.019</span>    <span style="color: #ff4500;">0.019</span>    <span style="color: #ff4500;">0.019</span> revlog.<span style="color: black;">py</span>:<span style="color: #ff4500;">622</span><span style="color: black;">&#40;</span>headrevs<span style="color: black;">&#41;</span>
   <span style="color: #ff4500;">177</span>/<span style="color: #ff4500;">70</span>    <span style="color: #ff4500;">0.010</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.019</span>    <span style="color: #ff4500;">0.000</span> <span style="color: black;">&#123;</span><span style="color: #008000;">__import__</span><span style="color: black;">&#125;</span>
       <span style="color: #ff4500;">13</span>    <span style="color: #ff4500;">0.006</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.006</span>    <span style="color: #ff4500;">0.000</span> <span style="color: black;">&#123;</span>method <span style="color: #483d8b;">'read'</span> of <span style="color: #483d8b;">'file'</span> objects<span style="color: black;">&#125;</span>
     <span style="color: #ff4500;">6326</span>    <span style="color: #ff4500;">0.002</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.004</span>    <span style="color: #ff4500;">0.000</span> cmdutil.<span style="color: black;">py</span>:<span style="color: #ff4500;">15</span><span style="color: black;">&#40;</span>parsealiases<span style="color: black;">&#41;</span>
       <span style="color: #ff4500;">93</span>    <span style="color: #ff4500;">0.002</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.006</span>    <span style="color: #ff4500;">0.000</span> cmdutil.<span style="color: black;">py</span>:<span style="color: #ff4500;">18</span><span style="color: black;">&#40;</span>findpossible<span style="color: black;">&#41;</span>
  <span style="color: #ff4500;">392</span>/<span style="color: #ff4500;">313</span>    <span style="color: #ff4500;">0.002</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.008</span>    <span style="color: #ff4500;">0.000</span> demandimport.<span style="color: black;">py</span>:<span style="color: #ff4500;">92</span><span style="color: black;">&#40;</span>_demandimport<span style="color: black;">&#41;</span>
     <span style="color: #ff4500;">7212</span>    <span style="color: #ff4500;">0.001</span>    <span style="color: #ff4500;">0.000</span>    <span style="color: #ff4500;">0.001</span>    <span style="color: #ff4500;">0.000</span> <span style="color: black;">&#123;</span>method <span style="color: #483d8b;">'split'</span> of <span style="color: #483d8b;">'str'</span> objects<span style="color: black;">&#125;</span></pre></div></div>

<p>Yep, definitely getting worse with more latency on the network connection.</p>
<p>Oh, and I&#8217;m using a recent version of hg:</p>
<pre>
$ hg --version
Mercurial Distributed SCM (version 2.0)

$ echo hello | ssh localhost hg -R /home/catlee/mozilla/try serve --stdio
145
capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
</pre>
<p>This doesn&#8217;t match what hg.mozilla.org is running:</p>
<pre>
$ echo hello | ssh hg.mozilla.org hg -R /mozilla-central serve --stdio
67
capabilities: unbundle lookup changegroupsubset branchmap stream=1
</pre>
<p>So it must be using an older version. Let&#8217;s see what mercurial 1.6 does:</p>
<pre>
$ mkvirtualenv hg16
New python executable in hg16/bin/python
Installing setuptools...

(hg16)$ pip install mercurial==1.6
Downloading/unpacking mercurial==1.6
  Downloading mercurial-1.6.tar.gz (2.2Mb): 2.2Mb downloaded
...

(hg16)$ hg --version
Mercurial Distributed SCM (version 1.6)

(hg16)$ echo hello | ssh localhost /home/catlee/.virtualenvs/hg16/bin/hg -R /home/catlee/mozilla/mozilla-central serve --stdio
75
capabilities: unbundle lookup changegroupsubset branchmap pushkey stream=1
</pre>
<p>That looks pretty close to what hg.mozilla.org claims it supports, so let&#8217;s time &#8216;hg out&#8217; again:</p>
<pre>
(hg16)$ time hg out ssh://localhost//home/catlee/mozilla/try
hg out ssh://localhost//home/catlee/mozilla/try  0.73s user 0.04s system 3% cpu 24.278 total
</pre>
<h1>tl;dr</h1>
<p>Finding missing changesets between two local repositories is <strong>6x slower with hg 1.6</strong> (4 seconds with hg 2.0 to 24 seconds hg 1.6). Add a few hundred people and machines hitting the same repository at the same time, and I imagine things can get bad pretty quickly.</p>
<p>Some further searching reveals that mercurial does support a <a href="http://mercurial.selenic.com/wiki/WireProtocol">faster</a> method of finding missing changesets in &#8220;newer&#8221; versions, although I can&#8217;t figure out exactly when this change was introduced.  There&#8217;s already a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=623505">bug on file</a> for upgrading mercurial on hg.mozilla.org, so hopefully that improves the situation for pushes to try.</p>
<p>The tools we use everyday aren&#8217;t magical; they&#8217;re subject to normal debugging and profiling techniques. If a tool you&#8217;re using is holding you back, find out why!</p>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2011/12/09/hg-performance/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Linux on a new Thinkpad T510</title>
		<link>http://atlee.ca/blog/2010/10/27/linux-on-a-new-thinkpad-t510/</link>
		<comments>http://atlee.ca/blog/2010/10/27/linux-on-a-new-thinkpad-t510/#comments</comments>
		<pubDate>Wed, 27 Oct 2010 19:19:27 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Hardware]]></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=759</guid>
		<description><![CDATA[I got a new Thinkpad T510 at work to replace my aging MacBook Pro. I asked for a Thinkpad instead of another MacBook because I wanted hardware with better hardware support, in particular the trackpad. I got into the habit of bringing a USB mouse everywhere I went because the trackpad on the MacBook was [...]]]></description>
			<content:encoded><![CDATA[<p>I got a new Thinkpad T510 at work to replace my aging MacBook Pro.  I asked for a Thinkpad instead of another MacBook because I wanted hardware with better hardware support, in particular the trackpad.  I got into the habit of bringing a USB mouse everywhere I went because the trackpad on the MacBook was so unreliable on linux.</p>
<p>So when my new T510 arrived, I was pretty excited.  And, except for one tiny problem (of the PEBKAC kind), transferring all my files from the old machine to the new one went flawlessly.</p>
<p>Here&#8217;s how I set up the new machine:</p>
<ul>
<li>Download image from <a href="http://www.sysresccd.org/Download">sysresccd.org</a>.  Follow the <a href="http://www.sysresccd.org/Sysresccd-manual-en_How_to_install_SystemRescueCd_on_an_USB-stick">instructions</a> to make a bootable USB drive.</li>
<li>Boot up computer off USB drive.  Resize the existing NTFS partition to be really small.  Add 2 new partitions in the new-free space: one for the boot partition for linux, and one to be encrypted and be formatted with lvm.</li>
<li>Format boot partition as ext3.  Setup encrypted partition with &#8216;cryptsetup luksFormat /dev/sda6; cryptsetup luksOpen /dev/sda6 crypt_sda6&#8242;.  Setup LVM with &#8216;pvcreate /dev/mapper/crypt_sda6&#8242;.  Setup two volumes, one for swap, and one for the root partition.</li>
<li>Connect network cable between old laptop and new one.  Configure local network.</li>
<li>Copy files from old /boot to new /boot.</li>
<li>Copy files from old / to new /.  Here&#8217;s where I messed up.  My command was: &#8216;rsync -aPxX 192.168.2.1:/ /target/&#8217;.</li>
<li>Install grub.</li>
<li>Reboot!</li>
</ul>
<p>At this point the machine came up ok, but wasn&#8217;t prompting to decrypt my root drive, and so I had to do some manual steps to get the root drive to mount initially.  Fixing up /etc/crypttab and the initramfs solved this.</p>
<p>However even after this I was having some problems.  I couldn&#8217;t connect to wireless networks with Network Manager.  I couldn&#8217;t run gnome-power-manager.  Files in /var/lib/mysql were owned by ntp!  Then I realized that my initial rsync had copied over files preserving the user/group <strong>names</strong>, not the uid/gid values.  And since I wasn&#8217;t booting off a Debian image, the id/name mappings were quite different.  Re-running rsync with &#8216;&#8211;numeric-ids&#8217; got all the ownerships fixed up.  After the next reboot things were working flawlessly.</p>
<p>Now after a few weeks of using it, I&#8217;m enjoying it a lot more than my MacBook Pro.  It boots up faster.  It connects to wireless networks faster.  It suspends/unsuspends faster.  It&#8217;s got real, live, page-up/page-down keys!  The trackpad actually works!</p>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2010/10/27/linux-on-a-new-thinkpad-t510/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>poster 0.7.0 released!</title>
		<link>http://atlee.ca/blog/2010/10/23/poster-0-7-0-released/</link>
		<comments>http://atlee.ca/blog/2010/10/23/poster-0-7-0-released/#comments</comments>
		<pubDate>Sat, 23 Oct 2010 16:04:13 +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=768</guid>
		<description><![CDATA[I&#8217;ve just pushed poster 0.7.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.7.0 fixes a few problems with 0.6.0, most notably: Added callback parameters to MutipartParam and multipart_encode so you can add progress [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just pushed poster 0.7.0 to the <a href="http://pypi.python.org/pypi/poster/0.7.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.7.0 fixes a few problems with 0.6.0, most notably:</p>
<ul>
<li>Added callback parameters to MutipartParam and multipart_encode so you can add progress indicators to your applications.  Thanks to Ludvig Ericson for the suggestion.
</li>
<li>Fixed a bug where posting to a url that returned a 401 code would hang. Thanks to Patrick Guido and Andreas Loupasakis for the bug reports.</li>
<li>MultipartParam.from_params will now accept MultipartParam instances as the values of a dict object passed in.  The parameter name must match the key corresponding to the parameter in the dict.  Thanks to Matthew King for the suggestion.</li>
<li>poster now works under python2.7</li>
</ul>
<p>poster 0.7.0 can be downloaded from the <a href="http://pypi.python.org/pypi/poster/0.7.0">cheeseshop</a>, or from <a href="http://atlee.ca/software/poster/dist/0.7.0/">my website</a>.  Documentation can be found at <a href="http://atlee.ca/software/poster/">http://atlee.ca/software/poster/</a></p>
<p>I&#8217;m planning on looking at python 3 compatibility soon.</p>
<p>Also, if anybody has suggestions on a reliable way to test the streaming http code, I&#8217;m open to suggestions!  My current methods result in intermittent failures because of the test harness I suspect.</p>
<p>poster&#8217;s code is now available on <a href="http://bitbucket.org/chrisatlee/poster">bitbucket</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://atlee.ca/blog/2010/10/23/poster-0-7-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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. [...]]]></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>1</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 this useful! [...]]]></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 counting Talos; [...]]]></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 [...]]]></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 [...]]]></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>
	</channel>
</rss>

