<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">

<channel>
	<title>Planet Twisted</title>
	<link>http://planet.twistedmatrix.com/</link>
	<language>en</language>
	<description>Planet Twisted - http://planet.twistedmatrix.com/</description>

<item>
	<title>Paul Swartz: sciyoshi » Using Akismet/TypePad AntiSpam with Django's new comments framework</title>
	<guid>http://blog.paulswartz.net/post/134255101</guid>
	<link>http://blog.paulswartz.net/post/134255101</link>
	<description>&lt;a href=&quot;http://sciyoshi.com/blog/2008/aug/27/using-akismet-djangos-new-comments-framework/&quot;&gt;sciyoshi » Using Akismet/TypePad AntiSpam with Django's new comments framework&lt;/a&gt;: Quick drop-in to connect Askimet to Django’s comment system</description>
	<pubDate>Thu, 02 Jul 2009 17:22:38 +0000</pubDate>
</item>
<item>
	<title>Thomas Vander Stichele: wordpress I hate you</title>
	<guid>http://thomas.apestaart.org/log/?p=954</guid>
	<link>http://thomas.apestaart.org/log/?p=954</link>
	<description>&lt;p&gt;After seeing that I possibly might have had some exploits run on my site again, I upgraded to wordpress 2.8&lt;/p&gt;
&lt;p&gt;After reading up on hardening wordpress, the official site mentions AskApache, some plugin that helps hardening.  I’m not too sure about it yet, because it wants to be writing .htaccess files in my directories and for that I have to open up more than I would want.  But hey, let’s give it a go.&lt;/p&gt;
&lt;p&gt;At some point it creates a username and password that you choose.  I go on and configure stuff, not knowing very well which of its many modules I’m supposed to activate, or why.&lt;/p&gt;
&lt;p&gt;I forget about it, and ten minutes later I check my mail.  I have a mail from AskApache.  With my login details.  And the password in plaintext.&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;Is the WordPress security model just fundamentally broken ?&lt;/p&gt;</description>
	<pubDate>Thu, 02 Jul 2009 12:52:15 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: 5luendo birthday party</title>
	<guid>http://thomas.apestaart.org/log/?p=952</guid>
	<link>http://thomas.apestaart.org/log/?p=952</link>
	<description>&lt;p&gt;Yesterday was cause for celebration.   We got together to celebrate five years of the Fluendo Group!&lt;/p&gt;
&lt;div class=&quot;wpg2tag-image&quot;&gt;&lt;a href=&quot;http://thomas.apestaart.org/log/?page_id=862&amp;amp;g2_itemId=71092&quot; title=&quot;01072009&quot;&gt;&lt;img src=&quot;http://thomas.apestaart.org/gallery/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=71093&amp;amp;g2_serialNumber=2&quot; id=&quot;IFid2&quot; width=&quot;150&quot; alt=&quot;01072009&quot; height=&quot;112&quot; class=&quot;ImageFrame_None&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The picture quality is bad, and not everyone is in it, but I just took it on a whim after marveling how many people were there.  I didn’t even know all of them – yes it’s gotten to that point.  67 months ago I arrived in Barcelona without the company even being created…&lt;/p&gt;
&lt;p&gt;We celebrated with mountains of cheese and rivers of wine which in the first year would have lasted us a few weeks and now only lasted an hour.&lt;/p&gt;
&lt;p&gt;As magical accidents sometimes happen, today is also the day Fluendo received the certification confirmation from Dolby for our DVD player.  It didn’t take long to land in the webshop, so finally &lt;a href=&quot;http://www.fluendo.com/shop/product/fluendo-dvd-player/&quot;&gt;our DVD player is up for sale!&lt;/a&gt; So you know what to get us for our birthday – a shop checkout with the dvd player in your cart.&lt;/p&gt;
&lt;p&gt;Good timing – that means that at this year’s &lt;a href=&quot;http://www.grancanariadesktopsummit.org/&quot;&gt;GUADEC/Desktop Summit&lt;/a&gt; I know what the answer will be to one of the most asked questions I get.&lt;/p&gt;
&lt;p&gt;This is the first GUADEC I’m going to with Kristien in tow, I hope she can manage.  I’ll be there from Monday through Friday, because the week is bookended by two weddings.  Looking forward to a GStreamer summit on Thursday discussing 1.0…&lt;/p&gt;</description>
	<pubDate>Thu, 02 Jul 2009 09:37:28 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: Tuesday</title>
	<guid>http://thomas.apestaart.org/log/?p=950</guid>
	<link>http://thomas.apestaart.org/log/?p=950</link>
	<description>&lt;p&gt;left work around 38 degrees C, got a haircut, went for some great tapas on my own reading Darkly Dreaming Dexter, went to a bar, met up with friends, an impromptu bbq plan was hatched, went to a lovely atico at Portal De L’Angel, barbecued in a soothing summer breeze, rode home on the back of a motorcycle hanging on for dear life.  All in all a typical Barcelona summer Tuesday.&lt;/p&gt;</description>
	<pubDate>Wed, 01 Jul 2009 10:07:32 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Paul Swartz: "Folks say that if you listen real close at the height of the full moon, when the wind is..."</title>
	<guid>http://blog.paulswartz.net/post/133035690</guid>
	<link>http://blog.paulswartz.net/post/133035690</link>
	<description>“Folks say that if you listen real close at the height of the full moon, when the wind is blowin’ off Nantucket Sound from the nor’ east and the dogs are howlin’ for no earthly reason, you can hear the awful screams of the crew of the Ellie May, a sturdy whaler Captained by John McTavish; for it was on just such a night when the rum was flowin’ and, Davey Jones be damned, big John brought his men on deck for the first of several screaming contests.”&lt;br /&gt;&lt;br /&gt; - &lt;em&gt;this year’s winner of the &lt;a href=&quot;http://www.bulwer-lytton.com/&quot;&gt;Bulwer-Lytton Fiction Content&lt;/a&gt;, which challenges people to create the worst first line of a novel.  Bulwer-Lytton, if you don’t know, was the one who first used “It was a dark and stormy night.”&lt;/em&gt;</description>
	<pubDate>Tue, 30 Jun 2009 17:58:22 +0000</pubDate>
</item>
<item>
	<title>Paul Swartz: YouTube tribute to MJ (via Slate V)</title>
	<guid>http://blog.paulswartz.net/post/132970718</guid>
	<link>http://blog.paulswartz.net/post/132970718</link>
	<description>&lt;br /&gt;&lt;br /&gt;YouTube tribute to MJ (via &lt;a href=&quot;http://www.slatev.com&quot;&gt;Slate V&lt;/a&gt;)</description>
	<pubDate>Tue, 30 Jun 2009 15:45:43 +0000</pubDate>
</item>
<item>
	<title>Jonathan Lange: Twisted huh?</title>
	<guid>tag:blogger.com,1999:blog-5733547231775030285.post-8536689109780623640</guid>
	<link>http://code.mumak.net/2009/07/twisted-huh.html</link>
	<description>One of the hallway conversations I've had a few times so far at EuroPython goes like this:&lt;br /&gt;&lt;br /&gt;A: Twisted's got some good stuff going for it, but I don't like the way it forces me to use Zope interfaces. It's too heavyweight?&lt;br /&gt;B: Huh? What do you mean? It doesn't make you do that.&lt;br /&gt;C: Yeah, there's lots of deep inheritance, which just feels really wrong.&lt;br /&gt;A: Right, I have to write too much code to get something simple working.&lt;br /&gt;B: Sorry, I have no idea what you mean. Can you give a concrete example?&lt;br /&gt;A, C: I can't think of one right now.&lt;br /&gt;&lt;br /&gt;To me, this is a very intriguing beginning to a real conversation. Do you know what A and C might mean here? I'd love to understand their points so that I can form an opinion.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/5733547231775030285-8536689109780623640?l=code.mumak.net&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Tue, 30 Jun 2009 15:23:03 +0000</pubDate>
	<dc:creator>jml (noreply@blogger.com)</dc:creator>
</item>
<item>
	<title>Paul Swartz: quote from a mug at the Farmer’s Diner in Quechee, VT</title>
	<guid>http://blog.paulswartz.net/post/132356086</guid>
	<link>http://blog.paulswartz.net/post/132356086</link>
	<description>&lt;img src=&quot;http://1.media.tumblr.com/2ERcULhJCpaycp9kc0eQDCybo1_500.jpg&quot; /&gt;&lt;br /&gt;&lt;br /&gt;quote from a mug at the Farmer’s Diner in Quechee, VT</description>
	<pubDate>Mon, 29 Jun 2009 16:32:03 +0000</pubDate>
</item>
<item>
	<title>Thomas Vander Stichele: Programming contest</title>
	<guid>http://thomas.apestaart.org/log/?p=948</guid>
	<link>http://thomas.apestaart.org/log/?p=948</link>
	<description>&lt;p&gt;Jan and Arek entered this year’s &lt;a href=&quot;http://www.icfpcontest.org/&quot;&gt;ICFP programming contest&lt;/a&gt;.  It’s a three day programming contest, so this morning they asked if they could swap their Friday project day for today to finish the contest.  They seem to be in the top third at the moment.&lt;/p&gt;
&lt;p&gt;Arek’s never been a fan of long meetings, but today’s standup meeting was particularly amusing with Arek urging everyone to keep focused and get out there quickly.  They had less than two hours left on the clock.&lt;/p&gt;
&lt;div class=&quot;wpg2tag-image&quot;&gt;&lt;a href=&quot;http://thomas.apestaart.org/log/?page_id=862&amp;amp;g2_itemId=71089&quot; title=&quot;29062009&quot;&gt;&lt;img src=&quot;http://thomas.apestaart.org/gallery/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=71090&amp;amp;g2_serialNumber=2&quot; id=&quot;IFid4&quot; width=&quot;150&quot; alt=&quot;29062009&quot; height=&quot;112&quot; class=&quot;ImageFrame_None&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt; &lt;em&gt;Spot the seven differences&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Amusingly, today they came to work with almost the same shirt on, by accident! I can only assume there is a big clothes factory in Poland where they have huge stock of the same fabric…&lt;/p&gt;
&lt;p&gt;90 minutes left, knock them dead, guys!&lt;/p&gt;</description>
	<pubDate>Mon, 29 Jun 2009 16:27:40 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: mach 0.9.5 ‘MMM…’ released</title>
	<guid>http://thomas.apestaart.org/log/?p=944</guid>
	<link>http://thomas.apestaart.org/log/?p=944</link>
	<description>&lt;p&gt;mach allows you to set up clean roots from scratch for any distribution or distribution variation supported.&lt;/p&gt;
&lt;p&gt;This release of mach contains fixes for Python 2.6, and adds Fedora 10 and 11, while fixing the archived Fedora locations.&lt;/p&gt;
&lt;p&gt;Get it from the &lt;a href=&quot;http://thomas.apestaart.org/projects/mach/&quot;&gt;mach&lt;/a&gt; project page.&lt;/p&gt;</description>
	<pubDate>Sat, 27 Jun 2009 21:57:34 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: moap vcs bisect</title>
	<guid>http://thomas.apestaart.org/log/?p=932</guid>
	<link>http://thomas.apestaart.org/log/?p=932</link>
	<description>&lt;p&gt;Next step on &lt;a href=&quot;http://thomas.apestaart.org/log/?p=921&quot;&gt;this weekend’s yakshave&lt;/a&gt;: a first implementation of moap vcs bisect!&lt;/p&gt;
&lt;p&gt;The interface is lifted from git, obviously, since that’s where most people will know the feature from.&lt;/p&gt;
&lt;p&gt;I implemented it first with CVS, so I could fix &lt;a href=&quot;https://sourceforge.net/tracker/index.php?func=detail&amp;amp;aid=2209631&amp;amp;group_id=24686&amp;amp;atid=382217&quot;&gt;this pychecker bug&lt;/a&gt; which was blocking Fedora from bumping the pychecker version from 0.8.17 (3 years old) to 0.8.18.  And sure enough, it picked out the commit I broke.&lt;/p&gt;
&lt;p&gt;While implementing and while dealing with CVS’s idea of how it stores CVS revisions and dates and so on, I googled and was amused to find this &lt;a href=&quot;http://wingolog.org/archives/2006/01/20/cvs-bisect&quot;&gt;first hit on google&lt;/a&gt; for the words cvs and bisect.  Clever Andy! And he cleverly sidestepped the problem I wrestled with by making the user specify two dates at the start instead of trying to figure it out from the checkout.  And all in lisp too!&lt;/p&gt;
&lt;p&gt;Then, to test that my VCS interface was sane, I implemented it for Subversion as well.  That took about 15 minutes, since Subversion is much more sane than CVS.  I tried the following command on a &lt;a href=&quot;http://www.flumotion.net/&quot;&gt;flumotion&lt;/a&gt; checkout:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;moap vcs bisect reset; moap vcs bisect start; svn up; moap vcs bisect good; svn up -r 3000; moap vcs bisect bad; MOAP_DEBUG=4 moap vcs bisect run ./test.sh&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;With test.sh containing&lt;br /&gt;
&lt;code&gt;test -e flumotion/component/consumers/gdp/gdp.py&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;(In other words, look for the commit that added this file.)&lt;/p&gt;
&lt;p&gt;Sure enough, it picked out this commit:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
&lt;code&gt;&lt;br /&gt;
[moap-trunk] [thomas@ana flumotion]$ moap vcs bisect diff&lt;br /&gt;
Index: /home/thomas/tmp/flumotion/configure.ac&lt;br /&gt;
===================================================================&lt;br /&gt;
--- /home/thomas/tmp/flumotion/configure.ac	(revision 6909)&lt;br /&gt;
+++ /home/thomas/tmp/flumotion/configure.ac	(revision 6908)&lt;br /&gt;
@@ -212,7 +212,6 @@&lt;br /&gt;
 flumotion/component/combiners/switch/Makefile&lt;br /&gt;
 flumotion/component/consumers/Makefile&lt;br /&gt;
 flumotion/component/consumers/disker/Makefile&lt;br /&gt;
-flumotion/component/consumers/gdp/Makefile&lt;br /&gt;
 flumotion/component/consumers/httpstreamer/Makefile&lt;br /&gt;
 flumotion/component/consumers/preview/Makefile&lt;br /&gt;
 flumotion/component/consumers/shout2/Makefile&lt;br /&gt;
Index: /home/thomas/tmp/flumotion/flumotion/component/consumers/Makefile.am&lt;br /&gt;
===================================================================&lt;br /&gt;
--- /home/thomas/tmp/flumotion/flumotion/component/consumers/Makefile.am	(revision 6909)&lt;br /&gt;
+++ /home/thomas/tmp/flumotion/flumotion/component/consumers/Makefile.am	(revision 6908)&lt;br /&gt;
@@ -11,7 +11,6 @@&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt; SUBDIRS = \&lt;br /&gt;
 	disker \&lt;br /&gt;
-	gdp \&lt;br /&gt;
 	httpstreamer \&lt;br /&gt;
 	preview \&lt;br /&gt;
 	shout2&lt;br /&gt;
Index: /home/thomas/tmp/flumotion/ChangeLog&lt;br /&gt;
===================================================================&lt;br /&gt;
--- /home/thomas/tmp/flumotion/ChangeLog	(revision 6909)&lt;br /&gt;
+++ /home/thomas/tmp/flumotion/ChangeLog	(revision 6908)&lt;br /&gt;
@@ -1,16 +1,5 @@&lt;br /&gt;
 2008-06-20  Thomas Vander Stichele  &amp;lt;thomas at apestaart dot org&amp;gt;&lt;br /&gt;
&amp;lt;/thomas&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-	* configure.ac:&lt;br /&gt;
-	* flumotion/component/consumers/Makefile.am:&lt;br /&gt;
-	* flumotion/component/consumers/gdp (added):&lt;br /&gt;
-	* flumotion/component/consumers/gdp/gdp.py (added):&lt;br /&gt;
-	* flumotion/component/consumers/gdp/__init__.py (added):&lt;br /&gt;
-	* flumotion/component/consumers/gdp/Makefile.am (added):&lt;br /&gt;
-	* flumotion/component/consumers/gdp/gdp.xml (added):&lt;br /&gt;
-	  Add a GDP consumer.&lt;br /&gt;
-&lt;br /&gt;
-2008-06-20  Thomas Vander Stichele  &amp;lt;thomas at apestaart dot org&amp;gt;&lt;br /&gt;
-&lt;br /&gt;
 	* flumotion/component/producers/gdp/gdp.py:&lt;br /&gt;
 	  Add error for http://bugzilla.gnome.org/show_bug.cgi?id=532364&lt;br /&gt;
&amp;lt;/thomas&amp;gt;&lt;/code&gt;
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;So, the feature is ready for testing.  It could use some more documenting, and some additional goodies like accepting arguments to moap vcs bisect start for example.&lt;/p&gt;
&lt;p&gt;Feedback appreciated!&lt;/p&gt;</description>
	<pubDate>Sat, 27 Jun 2009 19:32:07 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: jhbuild for python</title>
	<guid>http://thomas.apestaart.org/log/?p=930</guid>
	<link>http://thomas.apestaart.org/log/?p=930</link>
	<description>&lt;p&gt;Still on the &lt;a href=&quot;http://thomas.apestaart.org/log/?p=921&quot;&gt;yak shave expedition&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’ve written some simple scripts and files to set up and build python 2.3, 2.4, and 2.5 in separate prefixes to be able to test my software against these versions.&lt;/p&gt;
&lt;p&gt;If you’re interested, in theory it should be really simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://library.gnome.org/devel/jhbuild/unstable/getting-started.html.en&quot;&gt;Install jhbuild&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Check out my python jhbuild directory: svn co  &lt;a href=&quot;https://thomas.apestaart.org/thomas/svn/jhbuild/python&quot;&gt;https://thomas.apestaart.org/thomas/svn/jhbuild/python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;run ‘make’&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the README says, this should go on to build all versions of python, and install some scripts.&lt;/p&gt;
&lt;p&gt;After that, you just run py-2.3 to go into a shell with Python 2.3 on your path.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Don’t say I never did anything for you.&lt;/em&gt;&lt;/p&gt;</description>
	<pubDate>Sat, 27 Jun 2009 18:15:44 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: Python disassembly</title>
	<guid>http://thomas.apestaart.org/log/?p=927</guid>
	<link>http://thomas.apestaart.org/log/?p=927</link>
	<description>&lt;p&gt;As part of &lt;a href=&quot;http://thomas.apestaart.org/log/?p=921&quot;&gt;this weekend’s yakshave&lt;/a&gt;, I’m trying to implement a handler for STORE_MAP in pychecker.  STORE_MAP is a new opcode in Python 2.6, which speeds up dict building.&lt;/p&gt;
&lt;p&gt;So, for the first time I went under the hood of Python and figured out just enough to understand this problem.  It was a lot less scary than I thought it was going to be!&lt;/p&gt;
&lt;p&gt;It seems that using dis.dis(), one can easily dissassemble any python function into its opcodes.  This shows clearly where the behaviour is different between python 2.5 and python 2.6.&lt;/p&gt;
&lt;p&gt;Given the following function:&lt;br /&gt;
&lt;code&gt;f = lambda: {'a': 1, 'b': 2}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Python 2.6 gives:&lt;br /&gt;
&lt;code&gt;  1           0 BUILD_MAP                2&lt;br /&gt;
              3 LOAD_CONST               0 (1)&lt;br /&gt;
              6 LOAD_CONST               1 ('a')&lt;br /&gt;
              9 STORE_MAP&lt;br /&gt;
             10 LOAD_CONST               2 (2)&lt;br /&gt;
             13 LOAD_CONST               3 ('b')&lt;br /&gt;
             16 STORE_MAP&lt;br /&gt;
             17 RETURN_VALUE        &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I couldn’t find a good description of the output of dis.dis, but in my naiveness I am guessing the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first 1 maps to the line number in the code object where the function is found.&lt;/li&gt;
&lt;li&gt;The second column is the offset of the opcode and its arguments&lt;/li&gt;
&lt;li&gt;The third column is the opcode name&lt;/li&gt;
&lt;li&gt;The next column is the arguments for the opcode; in the case of CONST, it shows the index as well as the const object indexed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am assuming each opcode takes one address location, and each argument takes two; that maps with the address pointers in front of the opcodes.&lt;/p&gt;
&lt;p&gt;The opcodes are all &lt;a href=&quot;http://docs.python.org/library/dis.html&quot;&gt;documented&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, in human terms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;we start with BUILD_MAP, saying that we’ll create a new dictionary on the stack, with 2 entries.&lt;/li&gt;
&lt;li&gt;we load the constant with index 0 onto the stack (which happens to be the integer object ‘1′, the value of the ‘a’ key)&lt;/li&gt;
&lt;li&gt;we load the constant with index 1 onto the stack (which happens to be the string object ‘a’, the key for the ‘1′ value)&lt;/li&gt;
&lt;li&gt;STORE_MAP pops the key and the value off the stack, storing them in the dict.  Note that the key was indeed loaded on the stack after the value.  Now only the dictionary is left on the stack.&lt;/li&gt;
&lt;li&gt;Repeat LOAD_CONST, LOAD_CONST and STORE_MAP for the next set&lt;/li&gt;
&lt;li&gt;RETURN_VALUE returns the current value on the stack to the caller&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pretty simple, when you look at it twice.&lt;/p&gt;
&lt;p&gt;For the same code, python 2.5 gives:&lt;br /&gt;
&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; dis.dis(f)&lt;br /&gt;
  1           0 BUILD_MAP                0&lt;br /&gt;
              3 DUP_TOP&lt;br /&gt;
              4 LOAD_CONST               1 ('a')&lt;br /&gt;
              7 LOAD_CONST               2 (1)&lt;br /&gt;
             10 ROT_THREE&lt;br /&gt;
             11 STORE_SUBSCR&lt;br /&gt;
             12 DUP_TOP&lt;br /&gt;
             13 LOAD_CONST               3 ('b')&lt;br /&gt;
             16 LOAD_CONST               4 (2)&lt;br /&gt;
             19 ROT_THREE&lt;br /&gt;
             20 STORE_SUBSCR&lt;br /&gt;
             21 RETURN_VALUE        &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This code is slightly longer and more complicated.  Basically, LOAD_CONST, LOAD_CONST, STORE_MAP was implemented with DUP_TOP, LOAD_CONST, LOAD_CONST, ROT_THREE, STORE_SUBSCR&lt;/p&gt;
&lt;p&gt;It looks like DUP_TOP was needed because STORE_SUBSCR consumes the dictionary off the stack, and ROT_THREE is needed because the arguments are pushed on the stack in the wrong order.&lt;/p&gt;
&lt;p&gt;Seems like a nice and obvious improvement once you understand it.  An exercise for the reader is to profile whether this change actually makes things faster in practice.&lt;/p&gt;
&lt;p&gt;So, where does this leave me for pychecker ? It now looks deceptively simple.  STORE_MAP simply pops off two items of the stack.  There is nothing to check for, since we’re in a dictionary context.  So all my implementation needs to do is to pop 2 items off the stack, and that’s it.&lt;/p&gt;
&lt;p&gt;And thus it was commited to pychecker CVS.  Popping one item off the yak stack!&lt;/p&gt;</description>
	<pubDate>Sat, 27 Jun 2009 17:19:02 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: This weekend’s yak shave</title>
	<guid>http://thomas.apestaart.org/log/?p=921</guid>
	<link>http://thomas.apestaart.org/log/?p=921</link>
	<description>&lt;p&gt;The &lt;a href=&quot;http://projects.csail.mit.edu/gsb/old-archive/gsb-archive/gsb2000-02-11.html&quot;&gt;yak shave&lt;/a&gt; started yesterday evening.  The yak stack is actually a forked one this time, both of the forks involving pychecker.&lt;/p&gt;
&lt;p&gt;I might not remember everything in order, but in a nutshell the stack is something like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The original goal for this weekend at the beginning of the week was to release my cd ripper, morituri&lt;/li&gt;
&lt;li&gt;Something in its pychecker run did not run with pychecker 0.8.17 (the version still in Fedora, from 2006), and worked with pychecker 0.8.18 (my own build).  Fork point 1.&lt;/li&gt;
&lt;li&gt;While releasing moap this week, I realized that Freshmeat changed their remote API, which I should fix before I do another release of anything. Fork point 2.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fork point 1 continues here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I mailed Fedora’s pychecker maintainer, offering my help, and sending a patch to update to 0.8.18, which I built and installed locally.  He mailed back informing me about &lt;a href=&quot;https://sourceforge.net/tracker/index.php?func=detail&amp;amp;aid=2209631&amp;amp;group_id=24686&amp;amp;atid=382217&quot;&gt;this pychecker bug with anaconda&lt;/a&gt; which was blocking the upgrade.  Looking at that bug, it looked suspiciously like a bug triggered by code I added to pychecker last year.&lt;/li&gt;
&lt;li&gt;However, I’d like to confirm so in the easiest way.  git’s got this great feature, git bisect, and wouldn’it be nice if I could do that on pychecker now ? Hey, why not add bisection to moap ?&lt;/li&gt;
&lt;li&gt;CVS is actually not a very manageable VCS if you want to do fancy stuff.  It costs me a few hours to figure out how I should get a more-or-less usable date from a CVS checkout.  The final solution is similar to the reply to &lt;a href=&quot;http://stackoverflow.com/questions/1044651/how-to-programatically-get-the-latest-commit-date-on-a-cvs-checkout&quot;&gt;my stackoverflow question&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;moap vcs bisect run is now implemented and finds the commit that broke anaconda’s pychecking.  STACK POINTER IS CURRENTLY HERE.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fork point 2 continues here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;moap’s make check didn’t work because pychecker complained about the following code:&lt;br /&gt;
&lt;code&gt;ef func():&lt;br /&gt;
    d = { 'a': 1, 'b': 2}&lt;br /&gt;
    print d.keys()&lt;/code&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;which triggers, in python 2.6, the following warning:&lt;br /&gt;
&lt;code&gt;Object (d) has no attribute (keys)&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;I can’t let myself change code in moap without a working make check, so on to figuring out what’s wrong in pychecker&lt;/li&gt;
&lt;li&gt;After lots of debugging and print statements, I figure out that pychecker dispatches Python opcodes, and it silently drops the ones it doesn’t know about.  Python 2.6 added a new opcode, STORE_MAP, and so pychecker doesn’t properly handle the stack since it ignores the opcode.  I should error out on those opcodes. STACK POINTER IS CURRENTLY HERE&lt;/li&gt;
&lt;li&gt;Before I can fix that though, I decide I should make pychecker’s test suite error out on unknown opcodes.&lt;/li&gt;
&lt;li&gt;Of course, this will error out differently for different python versions, so I need different python versions on this machine.&lt;/li&gt;
&lt;li&gt;I could do that by hand, but I’d also like Twisted’s trial to run the testsuite, which also needs zope-interface in recent versions, which needs setuptools.  So hey, why not set up jhbuild stuff to build all these python versions ?&lt;/li&gt;
&lt;li&gt;Python 2.3 on my 64 bit machine doesn’t work with setuptools, so the newest Twisted without it is 1.3.0, and it takes a while to figure out why trial doesn’t run my testcases (it ends up being because 1.3.0 trial expects subclasses of twisted.trial.unittest.TestCase, not unittest.TestCase)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’ll blog about the useful products of my yak shave separately, for those who don’t enjoy descriptions of yak shavings, only outcomes.&lt;/p&gt;
&lt;p&gt;In general, I actually enjoy yak shaves.  They’re massive treasure hunts, you learn a lot, and you end up fixing a nice bunch of things all over the stack if you persevere.  But it’s probably more a mentality thing than anything else, and I really only indulge myself in these in my spare time.&lt;/p&gt;</description>
	<pubDate>Sat, 27 Jun 2009 12:17:54 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Glyph Lefkowitz: My Threat Model</title>
	<guid>tag:blogger.com,1999:blog-8729083.post-6245670475995046832</guid>
	<link>http://feedproxy.google.com/~r/glyph/~3/zKJ9puhbcHU/my-threat-model.html</link>
	<description>&lt;div&gt;&lt;font face=&quot;sans-serif&quot;&gt;As a &quot;computer guy&quot;, I am sometimes called upon by friends and family to opine on what makes a computer or a network secure.  Many of my colleagues are in the same situation.  As a &quot;networking guy&quot;, I get similar questions from even from experienced &quot;computer guys&quot;.&lt;br /&gt;&lt;br /&gt;Users have very peculiar ideas about security.  Users — and I include myself in this grouping — will become confused even in areas of the computing experience where billions of dollars have been spent trying to make the experience as easy and comprehensible as possible.  So it stands to reason that users will often be confused in the area of security, by its nature the &lt;i&gt;least&lt;/i&gt; usable and comprehensible area of computing.  Attacks are arcane, and, by definition, &lt;a href=&quot;http://www.matasano.com/log/1032/this-new-vulnerability-dowds-inhuman-flash-exploit/&quot;&gt;unexpected&lt;/a&gt; ways that software can be manipulated.  Yet, these attacks are very relevant to users, who want to understand what, exactly, they are vulnerable to and how to defend against it.&lt;br /&gt;&lt;br /&gt;It's basically impossible to try to understand computer security this way, let alone explain it.&lt;br /&gt;&lt;br /&gt;The important thing to remember in &lt;i&gt;any&lt;/i&gt; security situation is this: what do you have of value, and what is the threat to it?  Computer security professionals call the answer to this question the &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Threat_model&quot;&gt;threat model&lt;/a&gt;&quot;.  Stephen Colbert calls it the &lt;a href=&quot;http://www.comedycentral.com/shows/the_colbert_report/videos/threatdown/index.jhtml&quot;&gt;ThreatDown&lt;/a&gt;.  No matter what you call it, it's important to enumerate the threats that you're defending against.  Any security measure that you take which is not designed to protect you from a threat which you can, at the very least, imagine and describe, is just extra cost.&lt;br /&gt;&lt;br /&gt;In my case, people ask me about three broad classes of user: &lt;br /&gt;&lt;/font&gt;&lt;ol&gt;&lt;li&gt;&lt;font face=&quot;sans-serif&quot;&gt;users who have networked computers in a home, and use them for checking email, browsing the web, online shopping, and games,&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font face=&quot;sans-serif&quot;&gt;users who have networked desktop computers in a business, and use them for email, web, and business applications, and&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font face=&quot;sans-serif&quot;&gt;users who have networked server computers that are running server applications.&lt;/font&gt;&lt;/li&gt;&lt;/ol&gt;These users all have roughly similar threat models, so I'm going to lump them together for the sake of simplicity, with a nod to a few specific situations.&lt;br /&gt;&lt;br /&gt;I believe there are five major types of attacks which threaten average users on the internet today.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Automated attacks that attempt to connect to your computer and exploit a flaw in its operating system or in software that is running a server, and install malicious software on your computer.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;E-mail attacks, which attempt to deliver a message which will exploit a flaw in your desktop e-mail client to install malicious software on your computer.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Browser attacks, which attempt to get your browser (either with or without your consent) to visit a site which will exploit a flaw in your browser software to install malicious software on your computer.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Phishing attacks, which attempt to convince you to disclose information about yourself, such as bank account numbers, passwords, or personal details that can be used to access those other things.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Snooping attacks, which attempt to read information in transit between you and another computer.  Usually snooping attacks read passwords in an attempt to allow the attacker to impersonate you later.&lt;/li&gt;&lt;/ol&gt;Attacks 1-3 are all based on the same premise: software is flawed, and sometimes the flaws in it can be exploited to get it to do things that it should not do.  There are multiple resources under threat here: your computer itself (i.e. its processing power), your network connection, and the data stored on your computer.&lt;br /&gt;&lt;br /&gt;Attacks 4 and 5 are in a different class.  They're attempting to get you to reveal information over the network, either with or without your knowledge.  The resource under threat here is the information you are transmitting - in most cases, the information being sought is a token which allows you access to some resource; anything from a username and password to your facebook account (which allows for stealing your personal information or impersonating you) to a debit card number (which allows attackers access to the money in your bank account).&lt;br /&gt;&lt;br /&gt;I have fairly simple ways to protect yourself against each of these types of attack.  In a series of follow-up articles, I'll cover each of those strategies.  They should cover a wide variety of attacks with a minimum of effort and cost.  Of course, these defenses aren't perfect.  It's possible that &lt;a href=&quot;http://radian.org/&quot;&gt;someone who knows much more about security than I do&lt;/a&gt; will correct me, but if so, that's so much the better.&lt;br /&gt;&lt;br /&gt;More importantly, I will try to provide simple abstractions that allow you to reason about each type of attack without understanding the intricacies of the technology involved.  A major reason I've decided to try to write about this is that security vendors play upon the intuitive (and wrong) understanding that most people have about computer security: equating it with physical security, making their security widget the digital &quot;lock&quot; for the digital &quot;house&quot; of your computer.&lt;br /&gt;&lt;br /&gt;I am targeting this series at a fairly nontechnical audience.  I realize that my audience here mostly rates pretty high on the nerd spectrum; my hope is that you will agree with what I say sufficiently that this will be a useful resource for you to refer your less technical friends and family.  To maintain your interest, however, I'll also be embedding some details about the reasoning behind my own security practices.  See you next time!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;: I accidentally posted a draft of this rather than a final copy; some of the sentences and paragraphs were incomplete.  I hope that I've now corrected this.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/8729083-6245670475995046832?l=glyph.twistedmatrix.com&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/glyph/~4/zKJ9puhbcHU&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Fri, 26 Jun 2009 19:47:03 +0000</pubDate>
	<dc:creator>glyph (noreply@blogger.com)</dc:creator>
</item>
<item>
	<title>Jonathan Lange: Argh!</title>
	<guid>tag:blogger.com,1999:blog-5733547231775030285.post-4204614789025075071</guid>
	<link>http://code.mumak.net/2009/06/argh.html</link>
	<description>I upgraded karmic, and now Do &amp;amp; Banshee are broken. :(&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/5733547231775030285-4204614789025075071?l=code.mumak.net&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 25 Jun 2009 06:47:44 +0000</pubDate>
	<dc:creator>jml (noreply@blogger.com)</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: moap 0.2.7 released</title>
	<guid>http://thomas.apestaart.org/log/?p=915</guid>
	<link>http://thomas.apestaart.org/log/?p=915</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://thomas.apestaart.org/moap/trac/&quot;&gt;moap&lt;/a&gt; is a swiss army knife for maintainers and developers.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
This is MOAP 0.2.7, “MMM…”.&lt;/p&gt;
&lt;p&gt;Coverage in 0.2.7: 1424 / 1899 (74 %), 109 python tests, 2 bash tests&lt;/p&gt;
&lt;p&gt;Features added since 0.2.6:&lt;br /&gt;
- Added moap vcs backup, a command to backup a checkout to a tarball that&lt;br /&gt;
  can be used later to reconstruct the checkout.  Implemented for svn.&lt;br /&gt;
- Fixes for git-svn, git, svn and darcs.&lt;br /&gt;
- Fixes for Python 2.3 and Python 2.6
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I’ve been fixing things left and right for python 2.6, and in the process I noticed that moap hasn’t had a release for over a year.  This release contains mostly bug fixes collected over the year, and a new feature that isn’t implemented yet for all VCS’s.  Basically it’s an automatic replacement for something I was doing manually every time I removed an old GNOME cvs/svn/git checkout: figure out what’s in that tree that’s not in the repository (diffs, unversioned files, …), so I can delete everything else and free some disk space.&lt;/p&gt;
&lt;p&gt;The only problem with this release is that, after doing the release, I noticed that Freshmeat removed their XML-RPC interface.  Apparently they have some new kind of interface they want people to use.  Sigh.  But that means 0.2.8 is right around the corner!&lt;/p&gt;</description>
	<pubDate>Wed, 24 Jun 2009 20:41:20 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: Recovering from a lost /var on Fedora/Red Hat/CentOS</title>
	<guid>http://thomas.apestaart.org/log/?p=910</guid>
	<link>http://thomas.apestaart.org/log/?p=910</link>
	<description>&lt;p&gt;Last week, after upgrading my home desktop to F11, I had palimpsest tell me one of my disks was broken on the desktop machine.  The desktop is running on two 250 GB drives in software raid.  It was time to get new drives.&lt;/p&gt;
&lt;p&gt;After a weekend of fiddling with new 1 TB disks for my home desktop, trying failure scenarios, making sure the system can boot from each of the two drives, and waiting for the 4 hour resync of the software RAID in between each step, I finally closed up the desktop machine and cleaned up under my desk again, thinking I was done with my halfyearly messing about with broken disks.&lt;/p&gt;
&lt;p&gt;I guess I was tempting faith anyway.  Doing a routine operation on my home server after all the configuration stuff I’d done to set up asterisk last week, suddenly an rsync aborted, a journal errored out, a partition changed to being mounted read-only, and the log was full of scary drive errors.  Ouch.&lt;/p&gt;
&lt;p&gt;Well, that’s why I keep around a big box of old drives - for when some drive fails and I want to tempt fate even more by reusing an old drive that’s probably going to fail real soon too.  And anyway, I had just spent my hard drive piggybank on the new desktop drives.&lt;/p&gt;
&lt;p&gt;Luckily, I seemed to have a 400 GB SATA drive lying around that used to belong to my media center.  I don’t remember why I swapped it out, given that the media center has a 160GB drive for the OS (and two 1.5 TB raid drives for the data, of course), but this was a lucky break.  I booted with a rescue cd, and tried copying the root filesystem of my CentOS 5.2 home server partition to this new drive.  Which worked fine, except that /var was where I triggered an Input/Output error and some more drive errors in the kernel log.&lt;/p&gt;
&lt;p&gt;So, powered off, took out the broken drive, and put it in a USB chassis.  The advantage of a USB chassis is that you can easily just replug the drive to try again, instead of locking up your system terribly and having to reboot.  Sadly, /var was broken beyond repair.  I ran an e2fsck hoping to recover the contents, and that partly worked, but some of the important stuff is missing even from lost+found (apart from the annoying situation where you have to reconstruct file names, which I usually end up not bothering with).&lt;/p&gt;
&lt;p&gt;But really, how important can /var be ? Turns out, rather important.  As in, you need it to boot in the first place.  And also, it holds your rpm database.  Crap.&lt;/p&gt;
&lt;p&gt;Some Googling gave me some posts on how to reconstruct your rpm database from log files (using –justdb –noscripts –notriggers).  But to use those, you actually need those log files.  Where are those ? On /var as well.  Crap.  And they’re not in lost+found either.&lt;/p&gt;
&lt;p&gt;Ok, so time to get creative.  Here’s what I ended up doing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;create /var/lib/rpm, and run rpm –rebuilddb to end up with an empty rpm database&lt;/li&gt;
&lt;li&gt;Based on the contents of /usr/bin, figure out what packages ought to be installed:&lt;br /&gt;
&lt;code&gt;rpm -qf /etc/* | grep 'not owned' | cut -f2 -d' ' &amp;gt; /tmp/unowned&lt;br /&gt;
yum --enablerepo=c5-media --disablerepo=base --disablerepo=updates --disablerepo=addons --disablerepo=extras whatprovides `cat /tmp/unowned` | cut -f1 -d' ' | sort | uniq &amp;gt; /tmp/missing&lt;br /&gt;
yum --enablerepo=c5-media --disablerepo=base --disablerepo=updates --disablerepo=addons --disablerepo=extras install `cat /tmp/missing`&lt;/code&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This works by first listing all files that are not owned by rpm (on the first run, that’s all of them), figure out what packages can provide these files, then installing those packages.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Repeat the process for other important directories, like /bin, /sbin, /usr/sbin, /usr/lib, /usr/include, …&lt;/li&gt;
&lt;li&gt;Clean up .rpmnew files that don’t actually contain differences:&lt;br /&gt;
&lt;code&gt;find / -name *.rpmnew  | sed s/.rpmnew//g &amp;gt; /tmp/rpmnew&lt;br /&gt;
for c in `cat /tmp/rpmnew`; do echo $c; diff $c $c.rpmnew &amp;amp;&amp;amp; mv -f $c.rpmnew $c; done&lt;/code&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Same for *.rpmorig:&lt;br /&gt;
&lt;code&gt;find / -name *.rpmorig  | sed s/.rpmorig//g &amp;gt; /tmp/rpmorig&lt;br /&gt;
for c in `cat /tmp/rpmorig`; do echo $c; diff $c $c.rpmorig &amp;amp;&amp;amp; mv -f $c.rpmorig $c; done&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Inspect the remaining ones, and merge changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While it’s not an experience I hope to repeat any time soon, it worked out surprisingly well!&lt;/p&gt;</description>
	<pubDate>Wed, 24 Jun 2009 19:28:47 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: Upgrading to F11</title>
	<guid>http://thomas.apestaart.org/log/?p=908</guid>
	<link>http://thomas.apestaart.org/log/?p=908</link>
	<description>&lt;p&gt;I managed to completely skip updating to F10.  All my machines (work desktop, home desktop, laptop, media center) where running F9 without any real problems I worried about.&lt;/p&gt;
&lt;p&gt;But of course I was curious.  And, especially with the move to python 2.6, things I care about where bound to break.&lt;/p&gt;
&lt;p&gt;So, last weekend I took the plunge, and after little over a week here are my first impressions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Overall F11 looks slick.  Nice work on the artwork! I particularly liked the GDM background, looking like an ancient brushed metal object, reminding me of how I used to love playing Gods by the Bitmap Brothers.&lt;/li&gt;
&lt;li&gt;Apparently anaconda now has bugzilla integration, allowing you to file a bug directly from inside anaconda.  Luckily for Jeremy (who I assume still maintains it) it has some code in there to look for existing bug entries with the same backtrace.  Very nice!&lt;/li&gt;
&lt;li&gt;Of course, I wouldn’t have found out if I hadn’t run into exceptions in anaconda.  I ran into &lt;a href=&quot;https://bugzilla.redhat.com/show_bug.cgi?id=499544&quot;&gt; while setting up two completely new hard disks with 2 software raid partition and LVM on the second one.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I first installed my work desktop, as usual putting the new installation on a separate partition, keeping my old one around in case the install goes wrong or F11 just isn’t stable enough for me.  For me, that involves having a /mnt/alpha and /mt/omega partition between which I alternate.  At some point I should figure out if other people do this too and if it makes sense for anaconda to support something like this and at least allow me to keep my GRUB configuration for the older installation.  For now I do this manually, using a &lt;b&gt;huge&lt;/b&gt;upgrade text file I follow each time I upgrade, accumulating more and more steps each time I perform the procedure.&lt;/li&gt;
&lt;li&gt;On my home machine, when I booted into F11, as usual my second monitor didn’t work (I have a Radeon GeCube Pro 2400).  My own fault really - I should have tried to get a patch upstream into the default radeon driver the same way I sent a patch for the radeonhd driver that I still use.  A rebuild later, I at least had the old radeonhd driver rebuilt to get my second screen working again.&lt;/li&gt;
&lt;li&gt;Having the second screen now made me change my mind completely about the GDM wallpaper.  That lion on the right hand side that I didn’t see before completely ruins the style for me.  Sorry!&lt;/li&gt;
&lt;li&gt;Upon logging in to the work desktop, I had no network.  Completely puzzled as to why, until I figured out that I had to actually right-click on NetworkManager’s tray icon, choose to configure, and activate eth0 by default.  After some browsing it seems that this was a deliberate choice to increase security.  While I can possibly sympathize with the motivation for doing so, it really is terrible to change this by default and not provide *any* indication during or after installation.  At the very least, the following things could have been done:
&lt;ol&gt;
&lt;li&gt;provide a clear notice during installation, and allow a user to choose to enable it anyway, assuming the security risk&lt;/li&gt;
&lt;li&gt;the same, but during firstboot&lt;/li&gt;
&lt;li&gt;after logging in, having the network manager tooltip say ‘the network is disabled by default in this new release, here’s how you enable it&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I am not entirely sure what the security problems are with enabling the network after installation.  The default firewall is pretty locked down, SELinux is enabled by default, and there’s no way I can install updates without the network anyway.  But I’m sure that I could find huge bikeshedding threads on fedora-devel about this if I really cared why this was decided.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Upon logging in to the home desktop, I was greeted with a tooltip saying that one of my drives was going bad.  That was a nice touch!  Really good idea to have something like that be monitored by default. This prompted me to ponder to finally replace my desktop’s 250 GB PATA drives with real SATA drives - a story for another post.&lt;/li&gt;
&lt;li&gt;Various deprecation warnings pop up running various Python programs, including my own.  Flumotion needed a patch for running against 2.6 (I rebuilt and pushed to F11).  So I have some cleanup ahead, and I should revisit pychecker soon.&lt;/li&gt;
&lt;li&gt;The first piece of functionality I checked was Evolution’s Google Calendar integration.  It still seems a bit shaky, given that I had to restart Evolution a few times as it froze doing stuff with the net, but it does seem to work.  That means I will &lt;strong&gt;finally be able to accept work invitations done through Outlook and get them on my Google Calendar&lt;/strong&gt;! Awesome.  Now if only I didn’t have to manually configure each of the ten calendars I’m interested in…&lt;/li&gt;
&lt;li&gt;At work, when I played a video using XVideo, my machine instantly froze.  Seems to be &lt;a href=&quot;https://bugzilla.redhat.com/show_bug.cgi?id=496614&quot;&gt;a known bug&lt;/a&gt;.  The intel drivers are being rewritten.  I’ve never quite understood why rewriting is an excuse for breaking stuff that worked (I should check if Firewire video finally works reliably now when I have the chance, for example), but all in the name of progress I guess.&lt;/li&gt;
&lt;li&gt;I don’t know why it’s happening, but once in a while my screens blank.  Even in the middle of doing stuff. If I were a gamer I’d be hugely annoyed as my character would be shot through the head in that split instant.  The closest bug I can find is &lt;a href=&quot;https://bugzilla.redhat.com/show_bug.cgi?id=501534&quot;&gt;this one&lt;/a&gt;, where I commented. Hugely annoying bug because I don  event know how to begin debugging a bug like this that I can’t catch in the act.&lt;/li&gt;
&lt;li&gt;PulseAudio integration in GDM seems a bit fragile.  I have my pulseaudio configured to send audio to my media center pulseaudio server.  Sometimes, after choosing a username in GDM, it doesn’t manage to play the audio sample related to that action, and then GDM is stuck there not showing me the password entry dialog.  Pretty sure it’s due to blocking on pulseaudio, because when I kill it the password dialog appears.  Pretty painful bug for new users though.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All in all, not a bad first week experience, and seems like a solid release.  Now, off to rebuild bits and pieces, and clean up Python 2.6 deprecation warnings…&lt;/p&gt;</description>
	<pubDate>Wed, 24 Jun 2009 14:44:03 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Glyph Lefkowitz: A Chicken in Every Pot and a Python on Every Port</title>
	<guid>tag:blogger.com,1999:blog-8729083.post-87106454220329610</guid>
	<link>http://feedproxy.google.com/~r/glyph/~3/zNeud6C3Hnc/chicken-in-every-pot-and-python-on.html</link>
	<description>&lt;div&gt;&lt;font face=&quot;sans-serif&quot;&gt;&lt;a href=&quot;http://labs.twistedmatrix.com/&quot;&gt;Twisted Matrix Labs&lt;/a&gt; is bent on world domination.  We spend so much time working at the level of fine-grained minutæ that we sometimes forget the overarching plan.  So here's a step back: what is Twisted &lt;i&gt;for&lt;/i&gt;?&lt;br /&gt;&lt;br /&gt;Most people know at least part of Twisted's origin story.  I was working on a &lt;a href=&quot;http://divmod.org/trac/wiki/DivmodImaginary&quot;&gt;text-based game&lt;/a&gt;, and I wanted a networking layer, and discovered that there was really nothing available.  I decided to write something general to base the game's networking core on, so I would be able to use production-quality protocols rather than toy &quot;just for this game&quot; stuff.&lt;br /&gt;&lt;br /&gt;However, it wasn't just about the game.  That's a good thing, too, because the game has been falling behind quite a bit.  My game was just one example of code that you might want to write that could talk to a network, and my frustration was that despite large amounts of code being written to talk to networks, very little of it was directly usable by &lt;i&gt;other&lt;/i&gt; code, and even less of it could be combined.  A major culprit here is that most networking software is written in C, where there is a stark contrast between &quot;application&quot; and &quot;library&quot;; a conscious, deliberate effort has to be made to expose functionality as a library, both in the code and in the build process.&lt;br /&gt;&lt;br /&gt;Then there's the security situation.  &lt;a href=&quot;http://cwe.mitre.org/documents/vuln-trends/index.html&quot;&gt;A 2007 analysis of different types of vulnerability reports&lt;/a&gt; that buffer overflows were only recently overtaken by web application attacks, but are still the #2 for vulnerabilities overall, and #1 for OS vendor advisories.  Again, why is everybody still using all this network software written in C?  You can't even &lt;i&gt;have&lt;/i&gt; a buffer overflow in most high-level languages.  (The even more depressing thing here is that, as the web development community has moved to higher-level languages, the majority have moved to the &lt;i&gt;worst possible&lt;/i&gt; high-level language.  The vulnerability listings for web applications in that same report mostly have to do with flaws in PHP.)&lt;br /&gt;&lt;br /&gt;So, the goal of Twisted is to provide a high-quality, high-level, secure implementation of &lt;i&gt;every protocol&lt;/i&gt; spoken on the Internet.  We've achieved a lot, but there's still a long way to go.  Netcraft no longer seems to have any data on Twisted, because it is too low in the &quot;other&quot; category.  There's no site I'm aware of that does server market-share for DNS servers, but I'm betting that Twisted remains low in this category as well.&lt;br /&gt;&lt;br /&gt;I believe Twisted remains popular in a growing segment of the network applications market, that is to say, applications that don't fit neatly into a single protocol.  If you want to control DNS, HTTP, SIP, and XMPP from a single program, it's far easier in Twisted than in anything else.  However, I think we can do better.   I want Twisted to take on BIND, Apache, Asterisk and jabberd directly as a server in its own right, not an integration mechanism or library.&lt;br /&gt;&lt;br /&gt;One major area where Twisted is lacking is in focused, purpose-specific developers.  Apache has lots of people who are only interested in HTTP, Asterisk has people who are only interested in SIP, and libpurple has lots of people who are only interested in chat.  Twisted, by contrast, has excellent generalists, but few individuals to focus on the individual details of a single application.  I'm not sure how to recruit people who have that kind of monomaniacal focus to maintain individual components.  I think it's the details that such people would notice which is holding us back from being more competitive in the general server &quot;market&quot;, such as it is.&lt;br /&gt;&lt;br /&gt;This is a chicken-and-egg problem.  People interested in chat clients will often find libpurple before they find Twisted Words; people interested in web servers will often find Apache before they find Twisted Web.  Part of this is the lack of relevant conveniences and features, but probably an even bigger part is just our lack of a coherent web presence for those interest groups.  While I think that a lot of people looking for these things would be delighted to find something as easy to script and re-shape as Twisted is, they don't start out by looking for an omni-server platform.&lt;br /&gt;&lt;br /&gt;So go &lt;a href=&quot;http://twistedmatrix.com/trac/wiki/TwistedWeb&quot;&gt;update&lt;/a&gt; &lt;a href=&quot;http://twistedmatrix.com/trac/wiki/TwistedConch&quot;&gt;the&lt;/a&gt; &lt;a href=&quot;http://twistedmatrix.com/trac/wiki/TwistedMail&quot;&gt;web&lt;/a&gt; &lt;a href=&quot;http://twistedmatrix.com/trac/wiki/TwistedNames&quot;&gt;site&lt;/a&gt;, and take over the world!&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/8729083-87106454220329610?l=glyph.twistedmatrix.com&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/glyph/~4/zNeud6C3Hnc&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Tue, 23 Jun 2009 17:12:26 +0000</pubDate>
	<dc:creator>glyph (noreply@blogger.com)</dc:creator>
</item>
<item>
	<title>Duncan McGreggor: Mac OS X: Execute Shell Commands via Icon-Clicks</title>
	<guid>tag:blogger.com,1999:blog-8825992.post-5433611678644581810</guid>
	<link>http://feedproxy.google.com/~r/ElectricDuncan/~3/3UVtNvRO4tM/mac-os-x-execute-shell-commands-via.html</link>
	<description>&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://farm4.static.flickr.com/3393/3645070827_f425131ea6_o.png&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3393/3645070827_de16ec1c9b_m.jpg&quot; style=&quot;margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 240px; height: 167px;&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;My main development machine is a custom PowerBook running Ubuntu natively. I use it when I'm sitting on the couch, my office comfy chair, the futon, floor, etc. Every once in a while, though, I want to work at a desk from my 24&quot; iMac. Just to mix it up a little. However, that box is my gaming and web-browsing machine: it runs Mac OS X and that's the way I want to keep it. So, if I'm going to do work on the iMac, I need to ssh into the machines that have the environments set up for development.&lt;br /&gt;&lt;br /&gt;In the course of an average day of writing code, I'll connect to anywhere from 1 to 5 remote machines open up 5-10 ssh sessions in a terminal to each machine. If I'm at the iMac, this get's tedious. Today, it got tedious enough for me to do somthing about it. Here's what I want: to click on a Terminal icon and have an ssh connection automatically established to the box I need to work on. This it pretty easy on Linux and Windows, but I had no idea how to accomplish this on a Mac until tonight.&lt;br /&gt;&lt;br /&gt;I thought I'd share my solution; others may like it... but I'm betting there are some pretty cool ways of doing this that didn't occur to me -- so feel free to share yours!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Profile Hack&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;From previous messing about with the &lt;span style=&quot;font-family: courier new;&quot;&gt;open&lt;/span&gt; command, I knew I could open Terminal.app from the terminal:&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;open -n &lt;span class=&quot;s2&quot;&gt;&quot;/Applications/Utilities/Terminal.app&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;This got me part way there... if only I could dynamically execute a command upon login... so, yeah, I did something nasty:&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;vi ~/.bash_profile&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;And then:&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; ! -z &lt;span class=&quot;s2&quot;&gt;&quot;$REMOTE_CONNECTION&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;    &lt;/span&gt;ssh &lt;span class=&quot;nv&quot;&gt;$REMOTE_CONNECTION&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;nv&quot;&gt;    REMOTE_CONNECTION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;.command Files&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I was stumped at that point, until some googling revealed a nifty trick I didn't know about:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create a new file in your favorite editor, using the &lt;span style=&quot;font-family: courier new;&quot;&gt;.command&lt;/span&gt; extension&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Add the commands you want executed&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Save it and &lt;span style=&quot;font-family: courier new;&quot;&gt;chmod 755&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Double-click it and enjoy&lt;/li&gt;&lt;/ul&gt;So here's what I added to &lt;span style=&quot;font-family: courier new;&quot;&gt;rhosgobel.command&lt;/span&gt;:&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nv&quot;&gt;REMOTE_CONNECTION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;rhosgobel &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;br /&gt;   open -n &lt;span class=&quot;s2&quot;&gt;&quot;/Applications/Utilities/Terminal.app&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;The Obligatory Icon Tweak&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I then used the standard &quot;Get Info&quot; trick of icon copying: &quot;Get Info&quot; for Terminal.app, copy icon, &quot;Get Info&quot; for all my &lt;span style=&quot;font-family: courier new;&quot;&gt;.command&lt;/span&gt; files, paste icon.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;Usage&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://farm4.static.flickr.com/3381/3645070981_3a2dc3e58c_o.png&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3381/3645070981_edb963e877_m.jpg&quot; style=&quot;margin: 0pt 10px 10px 0pt; float: right; cursor: pointer; width: 240px; height: 115px;&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;Now, I just click my &quot;Shells&quot; menu, choose the destination, and start working on that machine. A new window or new tab opened with that instance of Terminal.app will give me a new session to that server, without having to manually ssh into it -- this is even more convenient than having an icon to double-click!&lt;br /&gt;&lt;br /&gt;One bit of ugly I haven't figured out how to remove: when I open a shell to a remote server, there's another shell opened at the same time with a &lt;span style=&quot;font-family: courier new;&quot;&gt;[Process completed]&lt;/span&gt; message.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/8825992-5433611678644581810?l=oubiwann.blogspot.com&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/ElectricDuncan/~4/3UVtNvRO4tM&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Sun, 21 Jun 2009 04:09:57 +0000</pubDate>
	<dc:creator>Duncan McGreggor (oubiwann@gmail.com)</dc:creator>
</item>
<item>
	<title>Kevin Turner (LJ): brunchbox burger with pineapple</title>
	<guid>http://keturn.livejournal.com/255079.html</guid>
	<link>http://keturn.livejournal.com/255079.html</link>
	<description>There's an &lt;a href=&quot;http://opensourcebridge.org/2009/wiki/Unconference_Session_Ideas&quot;&gt;open-source open-space conference&lt;/a&gt; Friday.  It's possible I want to talk about something but have forgotten what it was.  What do I host a session on?</description>
	<pubDate>Fri, 19 Jun 2009 08:01:09 +0000</pubDate>
</item>
<item>
	<title>Duncan McGreggor: A Sinfonia on Messaging with txAMQP, Part III</title>
	<guid>tag:blogger.com,1999:blog-8825992.post-8018168738559081016</guid>
	<link>http://feedproxy.google.com/~r/ElectricDuncan/~3/Xi5GBHBooNg/sinfonia-on-messaging-with-txamqp-part_18.html</link>
	<description>&lt;div&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;A Sinfonia on Messaging:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;http://oubiwann.blogspot.com/2009/06/sinfonia-on-messaging-with-txamqp.html&quot;&gt;The Voice of Business&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://oubiwann.blogspot.com/2009/06/sinfonia-on-messaging-with-txamqp-part.html&quot;&gt;The Voice of Architecture&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://oubiwann.blogspot.com/2009/06/sinfonia-on-messaging-with-txamqp-part_18.html&quot;&gt;A RabbitMQ and txAMQP Interlude&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Before we play our third voice in this three-part invention, we need to do some finger exercises. In particular, let's take a look at the concepts and tools we'll be using to implement and run our kilt store messaging scenario.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Messaging&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href=&quot;http://www.rabbitmq.com/faq.html#background&quot;&gt;RabbitMQ FAQ&lt;/a&gt; has this to say about messaging:&lt;br /&gt;&lt;b&gt; &lt;/b&gt;        &lt;blockquote&gt;Unlike databases which manage data at rest,        messaging is used to manage data in motion.  Use messaging to        communicate between and scale applications, within your enterprise,        across the web, or in the cloud.&lt;/blockquote&gt; Paraphasing Wikipedia's &lt;a href=&quot;http://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol&quot;&gt;entry on AMQP&lt;/a&gt;:&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;The AMQ protocol is for managing the flow of messages across an enterprise's business systems. It is middleware to provide a point of rendezvous between backend systems, such as data stores and services, and front end systems such as end user applications.&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;AMQP  Essentials&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;AMQP is a protocol for middleware servers -- servers that accept, route, and buffer messages. The &lt;a href=&quot;http://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.pdf?version=1&quot;&gt;AMQP specification&lt;/a&gt; defines messaging server &lt;a href=&quot;http://www.lego.com/&quot;&gt;LEGO&lt;/a&gt; blocks that can be combined in various ways and numbers, achieving any manner of messaging goals, whose final forms are as diverse as the combinations of the components.&lt;br /&gt;&lt;br /&gt;For the visually inclined, below is a simple diagram of the AMQ protocol. I've put multiple virtual hosts in the diagram to indicate support for multiple server &quot;segments&quot; (domains in the most general sense). There could just as easily be multiple exchanges and queues in each virtual host, as well. Likewise for publishers and consumers.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href=&quot;http://farm4.static.flickr.com/3349/3634123474_298f4f3e6e_o.png&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3349/3634123474_62b988082d.jpg&quot; style=&quot;border: 0pt none ; margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I highly recommend reading &lt;a href=&quot;http://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.pdf?version=1&quot;&gt;the spec&lt;/a&gt;: it is exceedingly clear at both intuitive and practical levels. To better understand the diagram above, be sure to read the definition of terms at the beginning as well as the subsections in 2.1 about the messaging queue and the exhange. Don't miss the message life-cycle section either -- you'll be reminded of circuitry diagrams and electronics kits, which is what AMQP really boils down to :-)&lt;br /&gt;&lt;br /&gt;The Advanced Messaging Queing Protocol specifies that the the protocol can be used to create exchanges, message queues, chain them together, and do all of this dynamically.  Any piece of code that has access to an API for your AMQP server can connect to it and communicate with other code -- using or creating simple messaging patterns or deeply complex ones. And everything in between.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;RabbitMQ Quickstart&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href=&quot;http://www.rabbitmq.com/&quot;&gt;RabbitMQ&lt;/a&gt; is a messaging system written in &lt;a href=&quot;http://erlang.org/&quot;&gt;Erlang&lt;/a&gt;, but in particular, it is an implementation of AMQP. The RabbitMQ web site provides documentation on &lt;a href=&quot;http://www.rabbitmq.com/install.html&quot;&gt;installing&lt;/a&gt; and &lt;a href=&quot;http://www.rabbitmq.com/admin-guide.html&quot;&gt;administering&lt;/a&gt; the messaging server. I run mine on Ubuntu, but since I've got a custom Erlang install, I didn't install the package (I dumped the source in &lt;span style=&quot;font-family: courier new;&quot;&gt;/usr/lib/erlang/lib&lt;/span&gt;). To participate in the code play for this blog series, you'll need to install RabbitMQ.&lt;br /&gt;&lt;br /&gt;Once you've got it installed, you'll need to start it up. If you've used something like Ubuntu's apt-get to install RabbitMQ, starting it up is as simple as this:&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;sudo rabbitmq-server&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;If you've got a custom setup like mine, you might need to do something like this (changing the defaults as needed):&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nv&quot;&gt;BASE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/lib/erlang/lib/rabbitmq-server-1.5.5/&lt;br /&gt;&lt;span class=&quot;nv&quot;&gt;BIN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BASE&lt;/span&gt;/scripts/rabbitmq-server&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;nv&quot;&gt;RABBITMQ_MNESIA_BASE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BASE&lt;/span&gt;/mnesia &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;nv&quot;&gt;RABBITMQ_LOG_BASE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/log/rabbitmq &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;nv&quot;&gt;RABBITMQ_NODE_PORT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;5672 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;nv&quot;&gt;RABBITMQ_NODENAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;rabbit &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;nv&quot;&gt;$BIN&lt;/span&gt; &amp;amp;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;A txAMQP Example&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that we've got a messaging server running, but before we try to implement out kilt store scenarios, let's take a quick sneak peek at txAMQP with a simple example having the following components:&lt;br /&gt;&lt;ul&gt;&lt;li style=&quot;color: rgb(102, 0, 0);&quot;&gt;a RabbitMQ server&lt;/li&gt;&lt;li style=&quot;color: rgb(0, 0, 153);&quot;&gt;a txAMQP producer&lt;/li&gt;&lt;li style=&quot;color: rgb(102, 0, 204);&quot;&gt;a txAMQP consumer&lt;/li&gt;&lt;/ul&gt;From reading the spec, we have a general sense of what needs to happen in our &lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;producer&lt;/span&gt;. It needs to:&lt;br /&gt;&lt;ul style=&quot;color: rgb(0, 0, 153);&quot;&gt;&lt;li&gt;connect to the RabbitMQ server&lt;/li&gt;&lt;li&gt;open a channel&lt;br /&gt;&lt;/li&gt;&lt;li&gt;send a message down the channel&lt;/li&gt;&lt;/ul&gt;Similarly, our reading lets us anticipate the needs of the &lt;span style=&quot;color: rgb(102, 0, 204);&quot;&gt;consumer&lt;/span&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li style=&quot;color: rgb(102, 0, 204);&quot;&gt;connect to the RabbitMQ server&lt;/li&gt;&lt;li style=&quot;color: rgb(102, 0, 204);&quot;&gt;open a channel&lt;br /&gt;&lt;/li&gt;&lt;li style=&quot;color: rgb(102, 0, 204);&quot;&gt;create an exchange and message queue on the RabbitMQ server, binding the two&lt;/li&gt;&lt;li style=&quot;color: rgb(102, 0, 204);&quot;&gt;check for in-coming messages and consume them&lt;/li&gt;&lt;/ul&gt;I have refactored some examples that the author of txAMQP &lt;a href=&quot;http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/#comment-681&quot;&gt;created&lt;/a&gt; and I've put them up &lt;a href=&quot;http://bazaar.launchpad.net/%7Eoubiwann/adytum-collection/Docs/files/head%3A/messaging/amqp/twisted/producer-consumer/&quot;&gt;here&lt;/a&gt;. Once you download the three Python files (and the spec file, one directory level up), you can run them in two separate terminals. In terminal 1, start up the consumer:&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;python2.5 consumer amqp0-8.xml&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;In terminal 2, fire off a message:&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;python2.5 producer amqp0-8.xml &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;br /&gt; &lt;span class=&quot;s2&quot;&gt;&quot;producer-to-consumer test message 1&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;After running the producer with that message, you should see the same text rendered in the consumer terminal window. You can also fire the message off first, then start up the consumer. The message is sitting in a queue on your RabbitMQ instance and will be available to your consumer as soon as it connects.&lt;br /&gt;&lt;br /&gt;Now that you see evidence of this working, you're going to be curious about the code :-) Go ahead and &lt;a href=&quot;http://bazaar.launchpad.net/%7Eoubiwann/adytum-collection/Docs/files/head%3A/messaging/amqp/twisted/producer-consumer/&quot;&gt;take a look&lt;/a&gt;. There are lots of comments in the code that give hints as to what's going on and the responsibilities that are being addressed.&lt;br /&gt;&lt;br /&gt;If you are familiar with Twisted, you may have noted that the code looks a little strange. If you're not, you may have noticed that the code looks normal, with the exception of extensive yield usage and the &lt;span style=&quot;font-family: courier new;&quot;&gt;inlineCallbacks&lt;/span&gt; decorator. Let me give a quick overview:&lt;br /&gt;&lt;br /&gt;Ordinarily, Twisted-based libraries and applications use the asynchronous &lt;a href=&quot;http://twistedmatrix.com/projects/core/documentation/howto/defer.html&quot;&gt;Twisted deferred idiom&lt;/a&gt;. However, there's a little-used bit of syntactic sugar in Twisted (for Python 2.5 and greater)  that lets you write async code that looks like regular, synchronous code. This was briefly explored &lt;a href=&quot;http://blog.mekk.waw.pl/archives/14-Twisted-inlineCallbacks-and-deferredGenerator.html&quot;&gt;in a post&lt;/a&gt; on another blog last year. The Twisted API docstring for &lt;span style=&quot;font-family: courier new;&quot;&gt;inlineCallbacks&lt;/span&gt; has a &lt;a href=&quot;http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.defer.html#inlineCallbacks&quot;&gt;concise example&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Briefly, the difference is as follows. In standard Twisted code, we assign a deferred-producing function's or method's return value to a variable and then call that deferred's methods (e.g., &lt;span style=&quot;font-family: courier new;&quot;&gt;addCallback&lt;/span&gt;):&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;someFunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;d1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;someAsyncCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;d1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_someCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;d2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anotherAsyncCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;d2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_anotherCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;With &lt;span style=&quot;font-family: courier new;&quot;&gt;inlineCallbacks&lt;/span&gt;, you decorate your function (or method) and yield for every deferred-producing call:&lt;br /&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nd&quot;&gt;@inlineCallbacks&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;someFunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;result1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;someAsyncCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;c&quot;&gt;# work with result; no need for a callback&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;result2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anotherAsyncCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;c&quot;&gt;# work with second result; no need for a callback&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Visually, this flows as regular Python code. However, know that the &lt;span style=&quot;font-family: courier new;&quot;&gt;yield&lt;/span&gt;s prevent the function from blocking and execution resumes as soon as the deferred has a result (which is assigned to the left-hand side). Since this latter idiom is used in txAMQP, I use it in the examples as well.&lt;br /&gt;&lt;br /&gt;Next, we finally reach our implementation!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;References&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.enterpriseintegrationpatterns.com/Chapter1.html&quot;&gt;&lt;/a&gt;The &lt;a href=&quot;http://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.pdf?version=1&quot;&gt;AMQP Spec&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The &lt;a href=&quot;https://launchpad.net/txamqp&quot;&gt;async Python library&lt;/a&gt; for AMQP&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.rabbitmq.com/&quot;&gt;RabbitMQ&lt;/a&gt;&lt;/li&gt;&lt;li&gt;A &lt;a href=&quot;http://app.arat.us/blog/?p=38&quot;&gt;txAMQP example&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/8825992-8018168738559081016?l=oubiwann.blogspot.com&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/ElectricDuncan/~4/Xi5GBHBooNg&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Thu, 18 Jun 2009 21:28:53 +0000</pubDate>
	<dc:creator>Duncan McGreggor (oubiwann@gmail.com)</dc:creator>
</item>
<item>
	<title>Duncan McGreggor: A Sinfonia on Messaging with txAMQP, Part I</title>
	<guid>tag:blogger.com,1999:blog-8825992.post-8225971593034234909</guid>
	<link>http://feedproxy.google.com/~r/ElectricDuncan/~3/NKiCEOnzXe0/sinfonia-on-messaging-with-txamqp.html</link>
	<description>&lt;div&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;A Sinfonia on Messaging:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;http://oubiwann.blogspot.com/2009/06/sinfonia-on-messaging-with-txamqp.html&quot;&gt;The Voice of Business&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://oubiwann.blogspot.com/2009/06/sinfonia-on-messaging-with-txamqp-part.html&quot;&gt;The Voice of Architecture&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://oubiwann.blogspot.com/2009/06/sinfonia-on-messaging-with-txamqp-part_18.html&quot;&gt;A RabbitMQ and txAMQP Interlude&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Prelude&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A complete messaging solution is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Inventions_and_Sinfonias_%28J._S._Bach%29&quot;&gt;three-part invention&lt;/a&gt; of business need, architecture, and implementation. In its final form, these three voices blend in harmony, with each one taking a dominant role depending upon which part of the solution one examines.&lt;br /&gt;&lt;br /&gt;Neither have I the ability nor skill to seamlessly weave three concepts together while clearly explaining their roles. Therefore, I will separate out the voices from each other and leave it as an exercise for the reader to construct an application and practice the principles involved, thus experiencing well-earned contrapuntal pleasures first-hand.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Introduction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As computing and data exchange systems increased in complexity over the past 30 years, so has the need for improvements -- and where possible, simplifications. Some of these efforts have been focused on decentralization of communications (shared, distributed load) and decoupling of messaging from applications (removing redundancy and increasing delivery speed/throughput). The first steps towards this were made in the 1990s with explorations in &quot;middleware&quot; application universe.&lt;br /&gt;&lt;br /&gt;Messaging, as we now refer to it in the industry, arouse from those middleware adventures: out of the business drive to refactor old software as new services to wider, more sophisticated audiences. With many new services replacing a single, monolithic application, formal and well-architected solutions were needed for creating, editing, and deleting shared data.&lt;br /&gt;&lt;br /&gt;From &lt;a href=&quot;http://en.wikipedia.org/wiki/Message_Oriented_Middleware&quot;&gt;Wikipedia&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;Message-oriented middleware (MOM) is infrastructure focused on message sending that increases the interoperability, portability, and flexibility of an application by allowing the application to be distributed over multiple heterogeneous platforms. It reduces the complexity of developing applications that span multiple operating systems and network protocols by insulating the application developer from the details of the various operating system and network interfaces.&lt;/blockquote&gt;AMQP (Advanced Message Queuing Protocol) is one of these protcols.&lt;br /&gt;&lt;br /&gt;In a &lt;a href=&quot;http://blogs.computerworld.com/new_ubuntu_linux_server_is_for_business&quot;&gt;recent blog post&lt;/a&gt; about Ubuntu as a business server, Vaughan-Nichols provides evidence for Ubuntu's and Canonical's commitment to enterprise, saying &quot;... the new [version of] Ubuntu also includes AMQP [...] support. AMQP is an important set of middleware and SOA [...] protocols.&quot;&lt;br /&gt;&lt;br /&gt;AMQP has demonstrated itself as a compelling protocol for messaging solutions, even to the point of being included in two Linux distributions. The code included in this blog series is &lt;a href=&quot;https://launchpad.net/txamqp&quot;&gt;txAMQP&lt;/a&gt;, an asynchronous Python AMQP library built with &lt;a href=&quot;http://twistedmatrix.com/&quot;&gt;Twisted&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Note that &lt;a href=&quot;http://twistedmatrix.com/pipermail/twisted-python/2008-September/018330.html&quot;&gt;last year&lt;/a&gt; I had planned to write a blog series on messaging with &lt;a href=&quot;http://metajack.im/2008/09/04/get-twisted-on-xmpp---the-future-of-twisted-words/&quot;&gt;Twisted and XMPP&lt;/a&gt;, but was unable to as a result of time constraints. These days, I'm working with AMQP instead of XMPP, but I still hold some hope that I'll be able to write an anolog for this series from the perspective of XMPP.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;The Voice of Business&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dipping into the future, &lt;a href=&quot;http://jira.amqp.org/confluence/display/AMQP/AMQP+1-0+Business+Requirements&quot;&gt;one of the goals&lt;/a&gt; for AMQP as developed by a special interest group is the following:&lt;br /&gt;&lt;blockquote&gt;Decentralized, Locally Governed Federated Mesh of AMQP Brokers with standardized Global Addressing. The killer application for AMQP is transacted secure business messages between corporations - e.g. send a banking confirmation message to confirms@bank.com [...]&lt;/blockquote&gt;I find this rather exciting due to my interest in &lt;a href=&quot;http://oubiwann.blogspot.com/search/label/uls&quot;&gt;ultra large-scale systems&lt;/a&gt;; scenarios like the one described above are the seeds for tomorrow's ULS systems :-)&lt;br /&gt;&lt;br /&gt;For now, though, let's look at a more immediate use for AMQP: a messaging protocol for shared services between departments in a small store. In this exercise, the voice of business is the primary melody; everything else (architecture and implementation) is done in support of this theme.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;An Example&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Fhionnlaidh MacGrudder creates hand-made kilts to order. He's got a sales guy who works with movie costume design shops and the like. He's got a web girl who wrote and maintains a custom  store front app. He's got a friend who does shipping and billing for him (as well as some other local Glen Orchy artisans). Until now, these three business &quot;groups&quot; associated with the kilt shop have been maintaining their own records, sometimes copying and updating them manually from each others' various export files.&lt;br /&gt;&lt;br /&gt;Fhionnlaidh's niece Fíona is programmer, business student, and is dating shipping guy's son. Horrified by the inefficiencies in her uncle's business processes (and tired of her boyfriend's father's complaints), she has proposed the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;sales guy will maintain customer contact info offer this as a service to the store and billing&lt;/li&gt;&lt;li&gt;the web store will dynamically update displayed data when sales guy changes it&lt;/li&gt;&lt;li&gt;the CRM will dynamically update displayed data when a web store customer updates their info&lt;/li&gt;&lt;li&gt;MacGrudder will have a new web page he goes to where all pending orders are presented with their full details; changes can be updated by a customer in real-time until MacGrudder has started working on the order&lt;br /&gt;&lt;/li&gt;&lt;li&gt;billing/shipping  guy will be notified instantly as soon as MacGrudder marks a kilt order as completed&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;This setup has the following benefits:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Contacts will be maintained in a single data store&lt;/li&gt;&lt;li&gt;There is zero latency between customer-driven updates and sales guy-driven updates&lt;/li&gt;&lt;li&gt;Customers have increased post-purchase flexibility with their orders&lt;/li&gt;&lt;li&gt;Shipping guy can plug into MacGudder's messaging and be notified when packages are ready for pickup&lt;/li&gt;&lt;li&gt;Everyone has more time for buttered scones and tea (especially shipping guy, who will no longer be making unneeded trips down the glen)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The following changes will be made to the current software:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Contacts will need to be merged into the CRM&lt;/li&gt;&lt;li&gt;A read/write data service for the contacts will need to be created&lt;/li&gt;&lt;li&gt;The CRM front-end will need to be upgraded to an AJAX-enabled version&lt;/li&gt;&lt;li&gt;The web store app will need to be updated to support AJAX&lt;/li&gt;&lt;li&gt;A new page will be created which displays the status of all orders and allows MacGrudder to change an order from &quot;pending&quot; to &quot;in-progress&quot; to &quot;completed&quot;&lt;/li&gt;&lt;li&gt;The current &quot;new order&quot; email notification code in the web app will need to be changed so that it uses the same messaging as MacGrudder's status page&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A new service needs to be created for shipping guy so that he can choose to be notified about pending pickups by email or he can check a web page or even make a query directly to the service, thus preventing unnecessary trips to MacGrudder's isolated little shop&lt;br /&gt;&lt;/li&gt;&lt;li&gt;After all the work is done, somone's going to need to order more scones&lt;/li&gt;&lt;/ul&gt;This example is not meant to fully justify messaging for businesses, but rather to provide a simple use case for which we can write some simple (and less than robust) code. It is a toy, but a conceptually useful one with a solid, concrete foundation.&lt;br /&gt;&lt;br /&gt;In the next installment, we'll review the business process (with diagrams!) and the explore the architecture of the system, before and after. Another post will take that architecture and combine it with MacGrudder's already extant infrastructure, reusing as much as possible. With that in place, we will have the opportunity to look at some RabbitMQ basics and some actual txAMQP code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;References&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.soa-in-practice.com/&quot;&gt;SOA in Practice&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Message_Oriented_Middleware&quot;&gt;Message-oriented middleware&lt;/a&gt; on Wikipedia&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol&quot;&gt;AMQP&lt;/a&gt; on Wikipedia&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The &lt;a href=&quot;http://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.pdf?version=1&quot;&gt;AMQP Spec&lt;/a&gt;&lt;/li&gt;&lt;li&gt;A &lt;a href=&quot;http://barryp.org/software/py-amqplib/&quot;&gt;synchronous Python library&lt;/a&gt; for AMQP&lt;/li&gt;&lt;li&gt;The &lt;a href=&quot;https://launchpad.net/txamqp&quot;&gt;async Python library&lt;/a&gt; for AMQP&lt;/li&gt;&lt;li&gt;A &lt;a href=&quot;http://app.arat.us/blog/?p=38&quot;&gt;txAMQP example&lt;/a&gt;&lt;/li&gt;&lt;li&gt;An &lt;a href=&quot;http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/&quot;&gt;intro to messaging and py-amqplib&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/8825992-8225971593034234909?l=oubiwann.blogspot.com&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/ElectricDuncan/~4/NKiCEOnzXe0&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Thu, 18 Jun 2009 17:59:07 +0000</pubDate>
	<dc:creator>Duncan McGreggor (oubiwann@gmail.com)</dc:creator>
</item>
<item>
	<title>Duncan McGreggor: A Sinfonia on Messaging with txAMQP, Part II</title>
	<guid>tag:blogger.com,1999:blog-8825992.post-4613470270539237100</guid>
	<link>http://feedproxy.google.com/~r/ElectricDuncan/~3/f3QMwXP6OwI/sinfonia-on-messaging-with-txamqp-part.html</link>
	<description>&lt;div&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;A Sinfonia on Messaging:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;http://oubiwann.blogspot.com/2009/06/sinfonia-on-messaging-with-txamqp.html&quot;&gt;The Voice of Business&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://oubiwann.blogspot.com/2009/06/sinfonia-on-messaging-with-txamqp-part.html&quot;&gt;The Voice of Architecture&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://oubiwann.blogspot.com/2009/06/sinfonia-on-messaging-with-txamqp-part_18.html&quot;&gt;A RabbitMQ and txAMQP Interlude&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;After writing the last blog post, I found a &lt;a href=&quot;http://www.enterpriseintegrationpatterns.com/&quot;&gt;fantastic site&lt;/a&gt; that focuses on messaging in the enterprise. I have really enjoyed the big-picture overview I get from some of the Martin Fowler signature books in this series, so I ordered &lt;a href=&quot;http://amazon.com/o/asin/0321200683/ref=nosim/enterpriseint-20&quot;&gt;a copy of this one&lt;/a&gt; too.&lt;br /&gt;&lt;br /&gt;On the web site, the authors give a nice example for messaging integration in &lt;a href=&quot;http://www.enterpriseintegrationpatterns.com/Chapter1.html&quot;&gt;Chapter 1&lt;/a&gt;. They provide a more detailed, supplier-version of the kilt store (we're doing &quot;manufacturing&quot; as opposed to distribution) with &quot;Widget-Gadget Corp&quot;, but the basic principles are the same. I highly recommend reading that entire page. I used it as the basis for much of this post.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Business Process Overview&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;At a top-level, we have the following business process for MacGrudder's kilt store:&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2468/3616902471_976fb0bbc7_o.png&quot; style=&quot;border: medium none ;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;These are represented by a sales guy or a web store, a third-party billing service, MacGrudder, and a third-party shipping service.&lt;br /&gt;&lt;br /&gt;Up until now, the sale process could be either a user deciding to buy something in the online store or the sales guy engaging with a customer. Both generated orders; neither shared resources. The web app interfaced with the payment gateway operating by billing/shipping guy. The sales guy had to call in his orders to the billing/shipping guy. Once orders were charged/approved, a printout was handed to MacGrudder, who then created the ordered kilt. Once completed, he'd set it aside for shipping guy to come box it up and slap a label on it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;The Voice of Architecture&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We're now ready to weave in the second voice of our &lt;a href=&quot;http://en.wikipedia.org/wiki/Inventions_and_Sinfonias_%28J._S._Bach%29&quot;&gt;three-part invention&lt;/a&gt;. MacGrudder's original infrastructure consists of silos of applications, functionality, data, and process. We want to interconnect these separated areas in order to reduce long-term overhead incurred by redundant components and data. Practically, we want to see the following changes:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://farm4.static.flickr.com/3662/3618180544_e906571e0f_o.png&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3662/3618180544_b5ca784ed1_m.jpg&quot; style=&quot;border: 0pt none ; margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 240px; height: 137px;&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-size: 85%;&quot;&gt;Unified orders&lt;/span&gt;&lt;/span&gt;: at the end of the sales process, there should be one abstraction of the &quot;order&quot;, regardless if the source was the web store, a phone call, or the sales guy. The order abstraction will be a message (or series of messages, for orders with multiple items; we'll be addressing only the simple case of a single item).&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://farm3.static.flickr.com/2441/3618361660_7b40df1bf9_o.png&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2441/3618361660_ca06012474_m.jpg&quot; style=&quot;border: 0pt none ; margin: 0pt 10px 10px 0pt; float: right; cursor: pointer; width: 240px; height: 137px;&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;span style=&quot;font-size: 85%;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;Unified validation and billing&lt;/span&gt;&lt;/span&gt;: at the end of the order creation process, there should be a validated order or an invalid order (e.g., if there were insufficient funds). At the end of the billing process, there should be an approved order that has be paid for via a single means (e.g., a single payment gateway, without bothering billing guy for manual entry). Additionally, once an order has been validated, messages should be sent to other components in the system.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://farm4.static.flickr.com/3299/3618662706_574433f920_o.png&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3299/3618662706_d0aebb491b_m.jpg&quot; style=&quot;border: 0pt none ; margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 240px; height: 137px;&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;span style=&quot;font-size: 85%;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Unified status&lt;/span&gt;&lt;/span&gt;: at the end of the manufacturing process, both the shipping guy and customers should be aware that the product has been completed and is ready to be sent: the shipping guy can connect to our messaging system (probably via a service) and the customer can be notified by email or by checking the order status in the web kilt store.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the next installment, we will finally start looking at the code. We'll look at the &quot;unified orders&quot; messaging solution after covering some basics with RabbitMQ and Twisted integration, and then see how far we get with implementation details and descriptions. Unified validation, billing, and status might have to be pushed to additional posts.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;References&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Enterprise Integration Patterns, &lt;a href=&quot;http://www.enterpriseintegrationpatterns.com/Chapter1.html&quot;&gt;Chapter 1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.soa-in-practice.com/&quot;&gt;SOA in Practice&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/8825992-4613470270539237100?l=oubiwann.blogspot.com&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/ElectricDuncan/~4/f3QMwXP6OwI&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Thu, 18 Jun 2009 17:58:53 +0000</pubDate>
	<dc:creator>Duncan McGreggor (oubiwann@gmail.com)</dc:creator>
</item>
<item>
	<title>Moshe Zadka: Hacker News: Groupthink’R'Us</title>
	<guid>http://moshez.wordpress.com/?p=265</guid>
	<link>http://moshez.wordpress.com/2009/06/18/hacker-news-groupthinkrus/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;Do you want to write a post that will appear in &lt;a href=&quot;http://news.ycombinator.com&quot;&gt;Hacker News&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;Here are a few blog headers that are sure to win you votes. Just write some filler and publish:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Any post containing the words “iterate” and “learn”. Bonus points if you can weave in words about how failing is good and failing fast is better. In your post, deride the need for any planning with an explanation that “you cannot assume anything”, and explain how the best way to succeed is to iterate quickly.&lt;/li&gt;
&lt;li&gt;Explain why ad-supported products are a bad idea. Bonus points if you quote pointless statistics, explain about freemium or announce why nano-, pico-, or milli- payment systems will finally enable people to pay for stuff.&lt;/li&gt;
&lt;li&gt;Explain why start-ups are better than big companies. Use one of the common themes of flexibility and ability to take risks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Seriously, all of these subjects have been done to death. We get them, really we do. The pros and cons have been explained, and making a more extreme post with an even more black-and-white picture is not what we want. And honestly? Debunking those is just as bad (done to death, we know it). Feel free to write such a post if it adds to your ego to have something rise to the top of HN. I’ll be here, waiting for more interesting posts there…&lt;/p&gt;
  &lt;a href=&quot;http://feeds.wordpress.com/1.0/gocomments/moshez.wordpress.com/265/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/comments/moshez.wordpress.com/265/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.wordpress.com/1.0/godelicious/moshez.wordpress.com/265/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/delicious/moshez.wordpress.com/265/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.wordpress.com/1.0/gostumble/moshez.wordpress.com/265/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/stumble/moshez.wordpress.com/265/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.wordpress.com/1.0/godigg/moshez.wordpress.com/265/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/digg/moshez.wordpress.com/265/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.wordpress.com/1.0/goreddit/moshez.wordpress.com/265/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/reddit/moshez.wordpress.com/265/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;img src=&quot;http://stats.wordpress.com/b.gif?host=moshez.wordpress.com&amp;amp;blog=2210753&amp;amp;post=265&amp;amp;subd=moshez&amp;amp;ref=&amp;amp;feed=1&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 18 Jun 2009 06:42:45 +0000</pubDate>
	<dc:creator>moshez</dc:creator>
</item>
<item>
	<title>Glyph Lefkowitz: Why Phones Lost</title>
	<guid>tag:blogger.com,1999:blog-8729083.post-7810741973090289231</guid>
	<link>http://feedproxy.google.com/~r/glyph/~3/rmECv6jkQ2I/why-phones-lost.html</link>
	<description>&lt;div&gt;This morning I was reading Antonio Rodriguez's &quot;&lt;a href=&quot;http://theonda.org/articles/2009/06/15/path-dependence-and-smartphones&quot;&gt;Path Dependence And Smartphones&lt;/a&gt;&quot; post, where he muses about different perspectives on the &quot;smartphone&quot; market; in particular the European / American divide outlined by Tomi Ahonen in &quot;&lt;a href=&quot;http://communities-dominate.blogs.com/brands/2009/06/a-tale-of-two-smartphones-us-vs-rest-of-world-compared.html&quot;&gt;A Tale Of Two Smartphones&lt;/a&gt;&quot;.  Antonio tends to think a few years ahead of his time, so I'm always interested in his take on trends like this.  It seems that he's very cautiously optimistic that the &quot;user customized mobile computer&quot; thing is an important trend, but he also notes that Mr. Ahonen believes that the &quot;[smartphone] operating system and any applications had ZERO bearing on the decision [of which phone to buy]. Not for mass market consumers&quot;; and maybe we're looking at this the wrong way.&lt;br /&gt;&lt;br /&gt;As I started thinking about my own reactions to this, I realized: I've heard this tune before.  Remember when pundits used to talk about &quot;convergence&quot; between television and computers?  Since the advent of the computer, futurists have been predicting the dawn of a strange new device: part computer, part television, part telephone, part vacuum cleaner.  What would it look like?&lt;br /&gt;&lt;br /&gt;Well, a few months ago, I feel like Paul Graham &lt;a href=&quot;http://www.paulgraham.com/convergence.html&quot;&gt;answered that question pretty definitively&lt;/a&gt;.  For years, we've wondered what you would get if you mixed computers and televisions.  In Mr. Graham's words: &quot;We now know the answer: computers.&quot;&lt;br /&gt;&lt;br /&gt;As a child of the digital age — I've been using computers with keyboards, mice, color displays, and networking almost as long as I've been able to read — I always found this conclusion somewhat obvious.  A few of the early computers that I had the opportunity to use, an Atari 800 and an Amiga 1000, both used televisions as monitors, so I have always thought of a television as an output device — you could plug it into a VCR, a computer, or a cable box, but fundamentally it was just a bag of pixels.&lt;br /&gt;&lt;br /&gt;I remember the exact moment that it dawned on me that computers were going to take over from TV: I was 14 years old, playing Myst for the first time, and monkeying with the configuration of &lt;a href=&quot;http://en.wikipedia.org/wiki/Extension_%28Mac_OS%29&quot;&gt;system extensions&lt;/a&gt; that were loaded on my computer in order to squeeze the last few ounces of performance so that the video clips in the game would play smoothly.  I remember thinking, &quot;This is just a problem with RAM and CPU.  In a few years computers will have so much of both that you'll be able to play &lt;i&gt;full screen&lt;/i&gt; video without even turning off any extensions.&quot;&lt;br /&gt;&lt;br /&gt;I, uh, had a pretty limited idea of how optimization worked at the time (the video was still jerky even after I turned off &lt;i&gt;all&lt;/i&gt; my extensions), but I am frequently reminded of this insight when I am watching YouTube movies on my LCD &quot;television&quot;.  That television, by the way, is just a monitor for a computer that runs Ubuntu so I can watch Hulu and YouTube.  I think maybe I have cable bundled with my internet service, because it's cheaper that way but I've never plugged it in to anything.&lt;br /&gt;&lt;br /&gt;I didn't realized how powerful &lt;i&gt;articulating&lt;/i&gt; this particular idea is until recently though, because I didn't realize just how much money is spent protecting obsolete infrastructure from the relentless onslaught of microprocessor technology.  Phone companies — which, increasingly, are combination cable/phone/internet companies — are stuck between a rock and a hard place.  As Internet service providers, they are a facilitator of the transition, and make a huge amount of money selling network services to people to make their computers more useful.  But, as cable companies, they want people to think that television is some special, extra expensive thing that needs to be delievered over a different cable.  As phone companies, both wired and wireless, they want people to think that voice and SMS data are special, extra expensive things that need to be delivered via special, magical wireless signals that can't be reduced to the simple and banal &quot;internet&quot;.  At the same time, especially as wired phone companies, they want the cost savings that comes from doing all of their networking as plain old IP, with no actual pesky phone circuits to worry about.  Except they still want to sell you the service as if the phone were a different thing from your &quot;internet&quot; connection.  (Whenever I see an ad for &lt;a href=&quot;http://www.comcast.com/Corporate/Learn/DigitalVoice/digitalvoice.html&quot;&gt;Comcast Digital Voice&lt;/a&gt;, I can't help but think, &quot;Do you think that's &lt;i&gt;air&lt;/i&gt; you're breathing?&quot;.)&lt;br /&gt;&lt;br /&gt;There's still a lot of speculation in each of these industries that some new, hybridized technology is going to create a special and unique relationship with the consumer.  But that's one thing Mr. Ahonen got right: the consumer doesn't care about your &quot;operating system&quot;.  They don't care about your &quot;applications&quot;.  They just care what they can do with their technology, and they care how much it costs to do so.  The thing is, computers do more, and cost less, than any other specialized, dedicated technology.  If your industry is fighting computers in the hopes of holding on to some residual value, you are going to lose.  Here's a simple formula:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;Computer + &lt;i&gt;X&lt;/i&gt; = Computer&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;Consider a few specific examples: the convergence of computers with television has resulted in three general categories of technology: YouTube (and other flash video sites, such as Hulu), Tivo (and other DVRs), and digital cable boxes with on-demand technology.  YouTube is a program you run on a computer to watch videos.  A Tivo is a computer (running linux) that is running a program to let you watch and record videos.  And those cable boxes are computers (running some crappy cut-down embedded OS) that let you watch videos on the cable company's terms.  Whether or not your customers care about choice, all these things are computers because it's fundamentally cheaper and easier for the &lt;i&gt;vendors&lt;/i&gt; to produce these things out of commodity PC components rather than specialized &quot;media&quot; electronics.&lt;br /&gt;&lt;br /&gt;But Mr. Graham neatly outlined that trend already, so let's move on to other industries.  What happens when you add a computer to an accounting ledger?  You get a computer program (like &lt;a href=&quot;http://www.dcit.com/&quot;&gt;BusinessMind&lt;/a&gt;, or QuickBooks) which lets you do accounting on your computer.  Computers and books?  The Kindle, which is a hand-held computer that lets you read books.  If you look a bit deeper, you'll find that the Kindle is actually a &lt;a href=&quot;http://www.amazon.com/gp/feature.html?ie=UTF8&amp;amp;docId=1000301301&quot;&gt;computer program&lt;/a&gt; that can run places other than its dedicated device.  Only crafty marketing folks prevent it from being more widely accessible; say, on your desktop or &quot;television&quot;.&lt;br /&gt;&lt;br /&gt;Let's get to the point of this whole schpiel: phones.  Phones are already computers, pure and simple.  They are just small computers with microphones and speakers, and soon, cameras and screens.  You can look at the exciting developments in the world of phones and see that this is so.  What are the hottest phones of the last few years?  The iPhone, which is a small Macintosh computer, and the G1, which is a small Linux PC.  Microsoft would have you believe that their small Windows PCs are equally relevant, even if they are clearly an also-ran in this category.  (Disclosure: I actually have a Windows Mobile phone, and I'm fairly happy with it, but I'll be glad when I can finally ditch it for Android.)  None of these &quot;phones&quot; does anything interesting in the area of phone-ness.  They don't have particularly awesome voice quality or particularly awesome reception or even particularly awesome voicemail, although the iPhone certainly raised the bar.  They're just better computers than the previous generation of &quot;phones&quot;; computers that can run a wider variety of programs.&lt;br /&gt;&lt;br /&gt;However, phones are still computers with weird restrictions, restrictions that are purely a function of the &quot;path dependence&quot; that Antonio mentions, which dragged them out of the muck and the mire of the telecom industry.  SMS is my favorite example of this: 10¢ to send a 140 character message.  How much does a tweet cost on twitter?  How much does an instant message cost on AIM, or Google Talk, or any IRC network you please?  If you were billed at SMS rates to read this post, it would have cost you $10; the cost of a decent paperback.  I know I'm wordy, but I'm not &lt;i&gt;that&lt;/i&gt; wordy.  If you were charged at SMS rates for a day's worth of casual web browsing, images and all, you'd probably have to take out a mortgage just to pay for it.  Phone companies have been able to sustain the myth that SMS data is somehow special and deserves to be treated as sacred and precious, fully 1000 times more expensive than the regular bytes you get off the internet, even at the obscene prices they charge for usage-based data plans.&lt;br /&gt;&lt;br /&gt;SMS is particularly egregious, but voice isn't that much different.  Phone companies charge such ridiculous rates for &quot;voice&quot; data that Skype built an entire profitable business around giving people the same service &lt;i&gt;for free&lt;/i&gt;, and only making money by piggybacking on the phone companies' greed and charging you when sending voice messages over phone networks rather than the internet.  I can't imagine casting the wasteful overhead of legacy phone networks in any sharper relief.&lt;br /&gt;&lt;br /&gt;So, we're not there yet, but the market pressure is tremendous to treat data as data, regardless whether it's voice, or SMS, or IM, or &quot;internet&quot; (in other words: everything else, including voice and SMS and IM messages which are sent via different mechanisms).  Until the advent of the recent crop of smartphones, it was difficult and expensive to get an unlimited data plan.  Now, unlimited data plans are the norm, except for &quot;tethering&quot; - using your phone as a proxy for your laptop.  The phone companies are still desperate to convince you that you should pay $60 per month for the privilege of having a USB dongle that you can plug into your laptop rather than just using the mobile IP endpoint — which, by the way, probably aleady has a USB port — that's already in your pocket.&lt;br /&gt;&lt;br /&gt;The &quot;mass market&quot; user might not care about operating systems or APIs, but they do understand that a bill with seventeen different break-out metered sections is a bald-faced attempt to rip them off, and a flat-rate or easy to understand pay-as-you-go plan with one number on it is better.&lt;br /&gt;&lt;br /&gt;To the extent that phones are not yet interchangeable, unrestricted mobile IP endpoints, it is due to the high barrier to entry to telecom providers, lack of regulation of misleading pricing schemes, and the symbiotic relationship between government and the telecom industry.  However, if one wireless carrier moves to provide simpler billing with more features, the others are forced to follow suit - even more so than cable companies and land-line providers, who can hold their customers hostage via development deals with local governments.  So, this progression is happening, albeit slowly.  For example, when AT&amp;amp;T introduced its iPhone plans, many of the other metered PDA and Blackberry plans, both on AT&amp;amp;T and other providers, began receding from their marketing materials.&lt;br /&gt;&lt;br /&gt;Fifteen years ago ... ugh, I feel old.  Let's say ... ten years ago, my computer was barely powerful enough to dedicate all of its processing power to playing one low-resolution movie that took up maybe half the screen.  I was still paying for internet over a phone line with a cap on the number of hours I could use it.  Today, I have real-time two-way video connection to anywhere in the world, 24-7, for a single flat rate.  I own a device that fits in the palm of my hand which contains days worth of continuous music, a library of dozens of books, and connects to the internet.&lt;br /&gt;&lt;br /&gt;So, back to that &quot;mass market consumer&quot;.  Maybe they don't care about my Python console or IRC chat or SSH access applications, but most &quot;mass market&quot; people do listen to music and read books.  And they're going to care about those features being on their phones, and remaining cheap enough that they can use those features without worrying that they'll go broke if they feel like changing out their playlist.  Also - nobody is really a &quot;mass market&quot; consumer, anyway.  You might not be technical, but maybe you're a golfer, or a swimmer, or a finance nerd.  You want to be able to check the weather on your mobile, or update your latest personal best lap time, or get updates when stocks hit certain price threshholds.  Nobody cares what APIs these apps use, or even whether you call them &quot;apps&quot;, but everybody has one extra thing they'd like their mobile to do.&lt;br /&gt;&lt;br /&gt;The increasingly ubiquitous, user-customizable, network connected, commodity pocket computer is exactly the technology that is going to deliver that.  It's going to have to become commoditized, which means it's going to be standardized, and secured, which means it's not going to be locked up in carrier notions of what's a &quot;text message&quot; and what's a &quot;voice call&quot; and allow for precise price segregation of every different type of data.&lt;br /&gt;&lt;br /&gt;In the future, almost every device will be a computer, albeit with specialized peripherals to assist with performing tasks.  If we're lucky, they will be networked together in standard ways to allow us to control all of them in a consistent and convenient way.&lt;br /&gt;&lt;br /&gt;This progression towards computers is good for all of us.  Trust the computer.  &lt;a href=&quot;http://en.wikipedia.org/wiki/Paranoia_%28role-playing_game%29&quot;&gt;The computer is your friend&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/8729083-7810741973090289231?l=glyph.twistedmatrix.com&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/glyph/~4/rmECv6jkQ2I&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Wed, 17 Jun 2009 23:39:35 +0000</pubDate>
	<dc:creator>glyph (noreply@blogger.com)</dc:creator>
</item>
<item>
	<title>Paul Swartz: America's Top Public High Schools | Newsweek Best High Schools | Newsweek.com</title>
	<guid>http://blog.paulswartz.net/post/124153217</guid>
	<link>http://blog.paulswartz.net/post/124153217</link>
	<description>&lt;a href=&quot;http://www.newsweek.com/id/201160/?q=2009/rank/1&quot;&gt;America's Top Public High Schools | Newsweek Best High Schools | Newsweek.com&lt;/a&gt;: B-CC (my HS alma mater) ranks 55th, up from 64th last year. Sure, it’s a bit of a bogus measurement (AP and IB tests taken / graduating seniors) but it’s nice to be listed.</description>
	<pubDate>Mon, 15 Jun 2009 20:50:27 +0000</pubDate>
</item>
<item>
	<title>Paul Swartz: CrossFit Faq: Explain the Works with Names (the Girls)</title>
	<guid>http://blog.paulswartz.net/post/124153205</guid>
	<link>http://blog.paulswartz.net/post/124153205</link>
	<description>&lt;a href=&quot;http://www.crossfit.com/cf-info/faq.html#WOD0&quot;&gt;CrossFit Faq: Explain the Works with Names (the Girls)&lt;/a&gt;: Since there’s a thunderstorm outside, I think I’ll be doing ‘Angie’ from my apartment.</description>
	<pubDate>Mon, 15 Jun 2009 20:50:26 +0000</pubDate>
</item>
<item>
	<title>Paul Swartz: Last year, I did “what’s in your bag?” on...</title>
	<guid>http://blog.paulswartz.net/post/124007826</guid>
	<link>http://blog.paulswartz.net/post/124007826</link>
	<description>&lt;img src=&quot;http://15.media.tumblr.com/2ERcULhJCoqwbgq39r0Kl0sgo1_500.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Last year, I did “what’s in your bag?” on Twitter.  To mix it up a bit, here’s a photo of the applications I’m running.  It’s pretty boring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pidgin (IM client, at the top left and top right)&lt;/li&gt;
&lt;li&gt;Firefox 3.0.11 (top middle, open to Google Reader)&lt;/li&gt;
&lt;li&gt;GNU Emacs 23.0.91.1 (bottom left, with code in the left pane and &lt;a href=&quot;http://zagadka.vm.bytemark.co.uk/magit/&quot;&gt;magit&lt;/a&gt; in the right)&lt;/li&gt;
&lt;li&gt;Miro trunk (bottom right; it’s got Joe Biden because I’m watching Sunday’s &lt;a href=&quot;http://www.msnbc.msn.com/id/3032608&quot;&gt;Meet the Press&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What’s running on your desktop?&lt;/p&gt;</description>
	<pubDate>Mon, 15 Jun 2009 15:39:39 +0000</pubDate>
</item>
<item>
	<title>Paul Swartz: Photo</title>
	<guid>http://blog.paulswartz.net/post/121499257</guid>
	<link>http://blog.paulswartz.net/post/121499257</link>
	<description>&lt;img src=&quot;http://9.media.tumblr.com/2ERcULhJCokdcbk51s4EvETEo1_500.jpg&quot; /&gt;&lt;br /&gt;&lt;br /&gt;</description>
	<pubDate>Thu, 11 Jun 2009 02:01:56 +0000</pubDate>
</item>
<item>
	<title>Moshe Zadka: Managing Large Twisted Projects</title>
	<guid>http://moshez.wordpress.com/?p=261</guid>
	<link>http://moshez.wordpress.com/2009/06/09/managing-large-twisted-projects/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;When working on a Twisted-centric project, it can be hard to recruit programmers. While Python, especially in recent years, has achieved main-stream status, Twisted is not quite there yet. It seems to be the case that recruiting Python programmers is, today, a solved problem. In the case where programmers unfamiliar with Python need to be recruited, resources (both free, cheap and expensive) abound for getting them up to par.&lt;/p&gt;
&lt;p&gt;In the Twisted world, especially for large projects, programmers who have no previous experience with Twisted will need to be recruited. In all software projects, time is of the essence. An efficient, effective, way to get Python programmers into Twisted is desired. This is the case in VMware Israel (formerly B-hive), where the flagship product AppSpeed has multiple portions written in Twisted.&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;Teaching Resources&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The broadest tutorial for Twisted is the “finger tutorial”. It leads the reader from writing the most basic finger server into a finger server supporting IRC and XML-RPC backends, going through a variety of Twisted programming techniques. Its broadness is also its chief downside, causing many newbies to learn many concepts which are irrelevant to their immediate needs, hiding the forest inside a density of trees.&lt;/p&gt;
&lt;p&gt;The Twisted howto collection is another excellent resources. Two primary howtos are the “Writing Servers” which covers, in a focused, no-nonsense manner, the steps needing to write a server for a new protocol. Very little depth and “why” are covered, which is often as much as an upside as a downside. The other important howto is “Deferred Execution”, covering the basics of deferreds. Several other resources for covering deferreds in-depth are available.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It is often the case that one, or more, of the people beginning a project have experience in Twisted. It is worthwhile to think how to attempt having a clean interface to those parts which need more such experience so that people writing other parts can hold their own with less such experience. Protocol details, for example, are often uninteresting, have a natural API and require non-trivial coding to deal with all the possibilities of packet portions arriving. The best wrapper for such details, if at all possible, is with an object whose methods return deferreds, and expose as few of the protocol details as possible.&lt;br /&gt;
An infrastructure containing such objects will help people learn Twisted in parts, while becoming productive programmers on the project early on.&lt;/p&gt;
&lt;p&gt;Another useful part of the architecture is to compensate for beginners’ mistakes. The most popular such mistake is trying to do too much in a single callback, halting the reactor loop. Two solutions, often used in tandem, are useful for this problem. One is to limit the damage by trying to separate loosely-coupled tasks into separate processes, and using infrastructure such as AMP to communicate between those. In case one reactor is paused for too long, the others will still function correctly. The other solution is watchdogging: have a relatively-frequent “LoopingCall” start early in the infrastructure do some measurable action (sending a UDP packet, touching a file) and have a separate watchdog check for this action. If too long passes without the action being performed, the reactor is not functioning up to par — and the process should be rebooted. This, of course, necessitates correct recovery from rebooting: a rudimentary persistence framework, to say the least.&lt;/p&gt;
&lt;p&gt;In places where long-running algorithms are required, or are merely easier to write, “deferToThread” is a useful abstraction. It allows the Twisted-beginner to shed all thoughts about events, and to write regular Python code. Those deferred-returning APIs will come in handy as they are used through reactor.blockingCallFromThread. It is useful to make sure blocking API meant to run in a different thread lives in separate modules — it makes code reviews easier when knowing in advance whether “time.sleep” or “reactor.callLater” is a bug.&lt;/p&gt;
&lt;p&gt;Deferred-oriented infrastructure, a communication platform and a watchdog are three things most large Twisted projects will sport at one point or another. The sooner they are done, and the better, the better overall quality of the project will be — especially in a project which is introducing a large portion of its programmers to Twisted.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In most big Twisted-oriented projects, a large portions of the programmers, even if Python experts, will not know Twisted before starting on the project. It is useful to plan for this in advance, allowing an easy Twisted initiation for the beginner. This can be done in the three prongs of focusing on unavoidable Twisted issues first (deferreds and non-blocking rather than low-level APIs), compensating in the architecture for common mistakes and allowing a transfer of non-Twisted Python knowledge by allowing threaded abstractions.&lt;/p&gt;
  &lt;a href=&quot;http://feeds.wordpress.com/1.0/gocomments/moshez.wordpress.com/261/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/comments/moshez.wordpress.com/261/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.wordpress.com/1.0/godelicious/moshez.wordpress.com/261/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/delicious/moshez.wordpress.com/261/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.wordpress.com/1.0/gostumble/moshez.wordpress.com/261/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/stumble/moshez.wordpress.com/261/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.wordpress.com/1.0/godigg/moshez.wordpress.com/261/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/digg/moshez.wordpress.com/261/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.wordpress.com/1.0/goreddit/moshez.wordpress.com/261/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/reddit/moshez.wordpress.com/261/&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;img src=&quot;http://stats.wordpress.com/b.gif?host=moshez.wordpress.com&amp;amp;blog=2210753&amp;amp;post=261&amp;amp;subd=moshez&amp;amp;ref=&amp;amp;feed=1&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Tue, 09 Jun 2009 09:14:07 +0000</pubDate>
	<dc:creator>moshez</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: matplotlib</title>
	<guid>http://thomas.apestaart.org/log/?p=900</guid>
	<link>http://thomas.apestaart.org/log/?p=900</link>
	<description>&lt;p&gt;Is python’s matplotlib and pylab just a twisty little maze of global variables and mass imports, making it impossible to learn your way around by introspection ? Or is it me ?&lt;/p&gt;
&lt;p&gt;I am getting lost in the difference between Axes, figure()’s and plot()’s…&lt;/p&gt;
&lt;p&gt;I’m sure this would all make more sense to me if I could recall my vague Matlab knowledge from university.&lt;/p&gt;</description>
	<pubDate>Fri, 05 Jun 2009 13:43:44 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Glyph Lefkowitz: Who Wants To Know?</title>
	<guid>tag:blogger.com,1999:blog-8729083.post-3930425108360017596</guid>
	<link>http://feedproxy.google.com/~r/glyph/~3/9yXUpO3wzEg/who-wants-to-know.html</link>
	<description>&lt;div&gt;Alternate Titles:&lt;br /&gt;&lt;h1&gt;I Have No Log File, Yet I Must Scream&lt;br /&gt;&lt;/h1&gt;or&lt;br /&gt;&lt;h1&gt;So You Logged It, Now What?&lt;/h1&gt;or&lt;br /&gt;&lt;h3&gt;This is why I don't want to have LOG_DEBUG in Twisted&lt;/h3&gt;Sometimes, when writing a program, you feel compelled to make the program emit some output which is peripheral to its operation.  The question is - who wants to know about that information?&lt;br /&gt;&lt;br /&gt;Maybe you're debugging the program, and you insert a simple 'print' statement to get some information about it.  Maybe your program is a network server, and you are recording the fact that a message was received and processed.  Maybe you're maintaining an old library routine, and you want it to emit a message that points to a newer, better version of that routine which is now preferred.  Finally, regardless of what kind of program you're writing, maybe it has produced an error that a user or administrator will need to deal with, and you would like to show it to them.&lt;br /&gt;&lt;br /&gt;This activity is referred to in several different contexts depending on how the messages are delivered, but it is most commonly known as &quot;logging&quot;.  It is critical to the operation of many, many different kinds of programs.  Unfortunately, it is one of the most poorly-understood and poorly-implemented areas of software in general.  Software is a veritable cornucopia of poorly-understood and poorly-implemented ideas, so that's really saying something.  You can see some of the more hilarious and visible examples of developers getting this wrong in the &quot;&lt;a href=&quot;http://thedailywtf.com/Series/Pop-up_Potpourri.aspx&quot;&gt;Pop-Up Potpourri&lt;/a&gt;&quot; series on the Daily WTF.&lt;br /&gt;&lt;br /&gt;It might seem odd that I lump together funny dialog boxes with &quot;logging&quot;.  A dialog box is a little square on your screen; a log message is some text in a file somewhere.  But they are very much the same thing, and they fail in very much the same way.  Log files just do it less visibly.&lt;br /&gt;&lt;br /&gt;The point that I hope to communicate here is that for every producer of information, there is a consumer.  When most programmers need to produce a &quot;log message&quot;, however, they are thinking only of getting the information out of their program in some format, &lt;i&gt;any&lt;/i&gt; format; not how that information is going to be used later.&lt;br /&gt;&lt;br /&gt;When I say &quot;most programmers&quot;, I most definitely include myself.  I'm probably guiltier than most. one of the reasons I'm writing about this in the first place is to work out some better approaches to the problem.&lt;br /&gt;&lt;br /&gt;Consider this output from the &quot;tomboy&quot; desktop sticky-notes program on Ubuntu Hardy.  If I start it from the command-line, I see this:&lt;br /&gt;&lt;blockquote&gt;&lt;font face=&quot;monospace&quot;&gt;[DEBUG]: NoteManager created with note path &quot;/home/glyph/.tomboy&quot;.&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;&gt;[INFO]: Initializing Mono.Addins&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;&gt;[DEBUG]: AddinManager.OnAddinLoaded: Tomboy.Tomboy&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;&gt;[DEBUG]:            Name: Tomboy.Tomboy,0.10&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;&gt;[DEBUG]:     Description: &lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;&gt;[DEBUG]:       Namespace: Tomboy&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;&gt;[DEBUG]:         Enabled: True&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;&gt;[DEBUG]:            File: /usr/lib/tomboy/Tomboy.exe&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;&gt;[DEBUG]: Updating note XML to newest format...&lt;/font&gt;&lt;br /&gt;&lt;/blockquote&gt;It goes on for several hundred more lines just at startup, and continues to produce messages as the program runs.  These messages are diligently classified into categories: DEBUG and INFO.  I'm sure they're useful to someone.  But why am I seeing them?  I just wanted to start a program to put some sticky notes on my desktop, and none of this information is useful to that task.&lt;br /&gt;&lt;br /&gt;I have to imagine that pretty much all of these messages are useful only to Tomboy's developers.  But, worse than the fact that I see them is the fact that if something really interesting happened — I discovered a critical bug, let's say — all of that log output which is being splatted onto my screen is going nowhere.  It is a book written on water.  (Well, a book written on video memory, which is pretty much the same thing.)  Meanwhile, thanks to the bug-reporting facilities in Ubuntu, I'm sure that I could opt to give the Tomboy developers a huge ton of mostly useless information, like the contents of my registers at the time that it crashed.&lt;br /&gt;&lt;br /&gt;Consider not just the placement of the messages (on my screen, where I certainly don't care about them) but their formatting.  Who is that elaborate right-justification of labels in the &quot;DEBUG&quot; output for, anyway?  It isn't for me, I don't want to see these messages in the first place.  I doubt it helps the developers, either; rather than just grepping for '[DEBUG]: File', now they need to put in a regular expression to collapse whitespace, or count the number of spaces that the justification happens to put in.  Presumably if this output is useful at all, it is useful in a search.&lt;br /&gt;&lt;h2&gt;Text Formatting and the Inevitable Descent into Log-Level Hell &lt;br /&gt;&lt;/h2&gt;The right-aligned pretty-printing is a beautiful illustration of a very common anti-pattern in logging: trying to convey structured information by messing with a textual format.  A developer wanting to write a message indicating that there is a problem with the program, left with the extremely narrow confines of a logging API which just takes a string, will often do something like this:&lt;br /&gt;&lt;blockquote&gt;&lt;font face=&quot;monospace&quot;&gt;log(&quot;*****&quot;)&lt;br /&gt;log(&quot;THIS SHOULD NEVER HAPPEN!  HELP!!!&quot;)&lt;br /&gt;log(&quot;*****&quot;)&lt;br /&gt;&lt;/font&gt;&lt;/blockquote&gt;Of course, this frantic wording doesn't help the output go anywhere but silently into a log file where it will be ignored.  But, perhaps if this is some server software, an administrator will notice this message and set up an alert that makes their blackberry buzz when they notice those particular words show up in the log file so they can ssh in and look for problems.&lt;br /&gt;&lt;br /&gt;Then the developer gets chastised by his manager for his un-informative error message, and updates it to be something clearer:&lt;br /&gt;&lt;blockquote&gt;&lt;font face=&quot;monospace&quot;&gt;log(&quot;Serious Error: phase inducers have been depolarized.  Contact engineering immediately.&quot;)&lt;br /&gt;&lt;/font&gt;&lt;/blockquote&gt;Of course this breaks the administrators' alerts, so after much discussion between programmers and admins, log levels are added so that admins &lt;i&gt;only&lt;/i&gt; get alerts when something &quot;really bad&quot; happens, where &quot;really bad&quot; is an agreed upon flag:&lt;br /&gt;&lt;blockquote&gt;&lt;font face=&quot;monospace&quot;&gt;log2(SERIOUS_ERROR, &quot;phase inducers have been depolarized.  Contact engineering immediately.&quot;)&lt;/font&gt;&lt;br /&gt;&lt;/blockquote&gt;Okay.  Now we've got a log level so admins can tell when their pagers should go off.  Except, different developers have different ideas about what &quot;serious&quot; means.&lt;br /&gt;&lt;blockquote&gt;&lt;font face=&quot;monospace&quot;&gt;log2(SERIOUS_ERROR, &quot;OMG I lost my cat Mittens.  Where is my cat?&quot;)&lt;/font&gt;&lt;br /&gt;&lt;/blockquote&gt;Clearly this is an abuse of the new &quot;severity&quot; flag that was added, but the cat-engineering team thinks that loss of a cat is pretty serious, so we add a new thing, a log &quot;system&quot;.&lt;br /&gt;&lt;blockquote&gt;&lt;font face=&quot;monospace&quot;&gt;log3(SYSTEM_CATS, SERIOUS_ERROR, &quot;OMG I lost my cat Mittens.  Where is my cat?&quot;)&lt;br /&gt;&lt;/font&gt;&lt;/blockquote&gt;Most logging systems stop in this general vicinity, but we still haven't solved the problem, which is that the log message has no structure and you can't tell what's going on without groveling around in a bunch of text files with regular expressions or manually reading each message.  Which cat was lost?  Which phase inducer was depolarized?  How do we get from a log message or alert to this information?  The 'log levels' solution to this problem is clearly untenable:&lt;br /&gt;&lt;blockquote&gt;&lt;font face=&quot;monospace&quot;&gt;logRidiculous(SYSTEM_CATS, ALERT_IF_YOU_LIKE_CATS, O_RLY, YA_RLY, SERIOUS_BUSINESS, BUT_NOT_TOO_SERIOUS, CAT_LEVEL(&quot;Mittens&quot;), &quot;OMG I lost my cat Mittens.  Where is my cat?&quot;)&lt;br /&gt;&lt;/font&gt;&lt;/blockquote&gt; More importantly, if you're writing a library, you have a bunch of other problems.  This diagnostic information needs to be logged somewhere, but what if this library is being used on a user's desktop machine?  Some of these messages are relevant to them as well.  How do you tell the user who is using a GUI that a cat has been lost?  How do you show them the picture of Mittens so they will recognize her if they see her?&lt;br /&gt;&lt;br /&gt;Everyone agrees that log messages need some &quot;small amount&quot; of information associated with them, but very few people can agree on what that information should be.  Even at the simplest layer, the idea of a &quot;level&quot;, there are lots of open questions.  Is the &quot;debug&quot; level for a programmer trying to debug something on their test rig, or is it for administrators trying to debug something in production?  Should there be a difference between those two things?  How serious does a problem have to be before warranting a &quot;critical&quot; classification?&lt;br /&gt;&lt;br /&gt;Once you're using logging code written by more than one programmer, or worse yet, more than one team, you're going to be facing this problem.&lt;br /&gt;&lt;h2&gt;The Particular Problem of Libraries&lt;/h2&gt;This is, of course, my main interest, since this is where the rubber meets the road for Twisted.  Libraries need to communicate to several different audiences:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;We need to tell developers using the library about the correct way to use the library at runtime.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We need to tell administrators of systems using the library about the status of the library and tasks they may need to perform to keep it functioning well.  (Clear your caches, restart the server, install a security update...)  We also need to provide administrators with information they can mine for statistics about how the library is performing; how many requests handled, where its resources are going, etc.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We need to notify users of applications using the library about things that the library is doing which may be relevant to them.  (A new message has arrived, a new printer is available... obviously this depends heavily on what the library does.)&lt;/li&gt;&lt;/ol&gt;Libraries, especially event-driven engines such as Twisted, libevent, and glib, have a particularly difficult time because they have to deal with all of these audiences simultaneously.  However, I think that any application or server which needs to do some kind of logging or user notification needs a subset of these features, so if any logging system could solve this problem, it could solve pretty much all logging problems.&lt;br /&gt;&lt;h2&gt;Type of Information by Type of Audience&lt;/h2&gt;&lt;h3&gt;Developers, Developers, Developers&lt;/h3&gt;Many languages don't have a solution to developer communication at all.  Python has one — the &lt;font face=&quot;monospace&quot;&gt;warnings&lt;/font&gt; module — but it is in many ways inadequate.&lt;br /&gt;&lt;br /&gt;The warnings module doesn't easily let you selectively see &lt;i&gt;which&lt;/i&gt; libraries you want to see warnings for.  If I'm developing an application A using libraries M, N, and O, which themselves have dependencies on X, Y, and Z respectively, I don't want to see warnings that M caused in X or that O caused in Z; those are problems for the maintainers of M and O.&lt;br /&gt;&lt;br /&gt;I am maintaining only A, so I want to see warnings caused by &lt;i&gt;my&lt;/i&gt; application in M, N, and O.  I can try to filter specifically by module, but unfortunately the&lt;br /&gt;only way of determining which library caused which issue is by directly&lt;br /&gt;examining stack depth, which is unreliable at best and misleading at&lt;br /&gt;worst.  Even if I could filter very accurately, it's hard to get a stand-alone report of warnings and deal with them as they're supposed to be.  Warnings show up to end-users as well, and to administrators looking at applications in production.  It's worth putting up with that to have at least some solution for communication with developers, but it would certainly be better if it didn't happen.&lt;br /&gt;&lt;br /&gt;Finally, it's easy to generate a huge amount of warning noise (and, especially as of Python 2.6, many libraries do).  With that much noise and no reporting functionality it's hard to the warnings you care about.&lt;br /&gt;&lt;br /&gt;A better solution for communicating for developers would be one which:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;allowed developers to declare somewhere what code they are working on and what code they are just using&lt;/li&gt;&lt;li&gt;recorded relevant warnings to a log file which was optimized, perhaps with an associated tool, for locating and removing the sources of the warnings&lt;br /&gt;&lt;/li&gt;&lt;li&gt;allowed end-users to easily communicate their warning data to developers without inundating them with irrelevant noise while using the application&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Administrators&lt;/h3&gt;To communicate with administrators there is a huge variety of options, but many of them depend on a lot of ad-hoc hackery by the admins themselves, which means they are inconsistent and therefore there is little reusable technology or standardized APIs available.&lt;br /&gt;&lt;br /&gt;Right now the gold standard for talking to admins seems to be just writing strings into a text file and hoping they have some facility to read it.&lt;br /&gt;&lt;br /&gt;A better solution for communicating with administrators would be one which:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;preserved structured data in an analysis-friendly format, rather than formatting it in human readable messages. (For most UNIX admins, I imagine some kind of structured text would be best, so &quot;grep&quot; would still work but more advanced tools could also be brought to bear.  I'm not sure what the tools in the Windows world look like.  The &quot;Event Viewer&quot; looks like maybe it's a step in the right direction, but its UI is incredibly primitive.)&lt;/li&gt;&lt;li&gt;provided easily-accessible hooks for dispatching different types of events to ad-hoc code to wire up to existing notification systems - &lt;i&gt;without&lt;/i&gt; significantly altering the behavior of the system doing the logging, if the logging hooks were broken, as admin-written code tends to be a bit flaky&lt;br /&gt;&lt;/li&gt;&lt;li&gt;included an enumerated list of events which administrators could inspect before they happened to run across them in log files&lt;/li&gt;&lt;/ul&gt;Although it's a crappy format in many ways, the Common Log Format for HTTP might serve as a good example.  Unfortunately it's too purpose-specific to extend to do more than what it already does, but lots of tools have been written to produce lots of interesting data from even that very simple standard.&lt;h3&gt;Desktop Users&lt;br /&gt;&lt;/h3&gt;There are two popluar cases for communicating with end-users.  One case is that you're actually running a program on their desktop and you want to tell them something.  Another is that you've got some code running in a web application which wants to tell them something &quot;out of bounds&quot;.&lt;br /&gt;&lt;br /&gt;On the desktop, there are fairly standard &quot;notification&quot; APIs for popping up little bubbles.  On the web, there are emerging conventions for these notifications, like a bar that descends from the top of the page to mimic the firefox 'do you want to remember this password?' UI element.  A good example of this is Stack Overflow's notification banner.&lt;br /&gt;&lt;br /&gt;Unfortunately both of these have a problem with scale and with timing.  If your application suddenly encounters a large number of errors, it will flood the user's screen.  If the user isn't present when a notification occurs (or navigates away), the bubbles or banners may disappear.&lt;br /&gt;&lt;br /&gt;A better way to talk to end-users would be:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;for desktop applications, a mini-email interface, which records notifications in a scrolling list so that users can inspect notifications that occur while they're away.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;for web applications, a standard API so that multiple applications on a single site (or even, potentially, on different sites) can drop notifications into a queue which can be displayed appropriately.  (Since websites tend to have strong preferences to control their own design, an actual standard widget might not be possible, but it would be nice.)&lt;/li&gt;&lt;li&gt;for both of these, a standard protocol which would enable notifications to be easily streamed to different computers or mobile devices without needing to reconfigure &lt;br /&gt;&lt;/li&gt;&lt;li&gt;a specific classification of messages at the API level, saying, &quot;I want to tell the end-user about this&quot;.  Messages about crashes, etc, should be displayed as an option to send information to the developer.  In the context of a web application this can be done automatically and silently; in a desktop app there would need to be some channel set up for sending that information.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Let's not forget that administrators are users too.  Everything that happens in a server's notification APIs should be able to be trivially filtered and redirected to administrator's desktop machine (or their phone) so they can immediately notice when something has gone wrong.&lt;br /&gt;&lt;h3&gt;Appendix A: Optimization and Dynamic Instrumentation&lt;/h3&gt;This doesn't fit into the &quot;figure out what you need to say and who you need to say it to&quot; theme of the rest of the requirements here, but it is nevertheless important.  If you make heavy use of a logging system, especially one where you have lots of messages that are logged &quot;just in case&quot; and rarely displayed, you will quickly discover that it's consuming a lot of resources.&lt;br /&gt;&lt;br /&gt;The work to calculate what goes into a log message shouldn't be done unless the message is actually going to be emitted.  Similarly, it should be easy to dynamically add and remove log events from particular methods or particular objects without modifying their code.  The best way to do this is to keep the logging entirely separate and add it at the level of methods and functions, rather than ad-hoc in the middle of application code.  Sometimes, of course, you want to emit log messages at a very particular point, but in general it should be easy to add instrumentation to a method without modifying its code, to avoid cluttering up application logic with lots of &quot;just in case&quot; debug messages.&lt;br /&gt;&lt;h2&gt;What Can Do This?&lt;br /&gt;&lt;/h2&gt;I'm not aware of any logging system that can already do these things.  We'd have to write a new one.  This essay was largely composed due to my desire to understand what I thought a &quot;good&quot; logging system would do.  It might be too ambitious.&lt;br /&gt;&lt;br /&gt;There are a few fundamental units which are missing from most logging systems.  While lots of logging systems have various ways to indicate subtle and nuanced levels of urgency, few have a way to indicate &lt;i&gt;who&lt;/i&gt; a message might be relevant to.  Logging systems also generally don't have a good way to associate structured information along with a log message.&lt;br /&gt;&lt;br /&gt;Twisted's logging mechanism does have a free-form dictionary associated with each message, but that's not much help unless you impose your own structure on it, which means you have to build all this infrastructure anyway.  It is, at least, possible to treat the Twisted system as a kernel which this could be based upon.&lt;br /&gt;&lt;br /&gt;In order to produce an enumeration of events before the events are actually logged, this API will require pre-declaration of log messages.  This might be too much of a burden, since sometimes you want to just stick a log message into the middle of some code so that you can see if it happens.  So, in practice, it's more likely that pre-declaration will need to be optional and you'll need to be able to associate ad-hoc data and have it still be persisted along with your message.&lt;br /&gt;&lt;br /&gt;There will need to be some way for communicating both the structured data of an event and the human-readable text associated with that event — preferably in a way which can be internationalized.&lt;br /&gt;&lt;br /&gt;There's also a bunch of UI, web, and protocol standardization work that would need to be done.  Luckly, that's independent of the actual log machinery; if it already existed it would be a trivial matter to hook it up.  In the meanwhile, something that did all of this but just used existing facilities, like the desktop notification spec, status icons and email, would still be immensely useful.&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/8729083-3930425108360017596?l=glyph.twistedmatrix.com&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/glyph/~4/9yXUpO3wzEg&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Thu, 04 Jun 2009 21:27:50 +0000</pubDate>
	<dc:creator>glyph (noreply@blogger.com)</dc:creator>
</item>
<item>
	<title>Jp Calderone: April - May Reading List</title>
	<guid>http://jcalderone.livejournal.com/45509.html</guid>
	<link>http://jcalderone.livejournal.com/45509.html</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Green Mars&lt;/u&gt;. Kim Stanley Robinson.&lt;/li&gt;
&lt;li&gt;&lt;u&gt;Blue Mars&lt;/u&gt;. Kim Stanley Robinson.&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Thu, 04 Jun 2009 13:52:42 +0000</pubDate>
</item>
<item>
	<title>Paul Swartz: the peanuts I could be eating with Geico</title>
	<guid>http://blog.paulswartz.net/post/117634415</guid>
	<link>http://blog.paulswartz.net/post/117634415</link>
	<description>&lt;img src=&quot;http://9.media.tumblr.com/2ERcULhJCoabl2qs7xnlxDT0o1_500.jpg&quot; /&gt;&lt;br /&gt;&lt;br /&gt;the peanuts I could be eating with Geico</description>
	<pubDate>Thu, 04 Jun 2009 01:15:01 +0000</pubDate>
</item>
<item>
	<title>Jonathan Lange: pyflakes now warns about unused local variables</title>
	<guid>tag:blogger.com,1999:blog-5733547231775030285.post-8847071679260347539</guid>
	<link>http://code.mumak.net/2009/06/pyflakes-now-warns-about-unused-local.html</link>
	<description>I finally got around to finishing my fix for &lt;a href=&quot;http://divmod.org/trac&quot;&gt;Divmod&lt;/a&gt; bug &lt;a href=&quot;http://divmod.org/trac/ticket/2718&quot;&gt;#2718&lt;/a&gt; -- Warn about unused variables in methods in &lt;a href=&quot;http://www.divmod.org/trac/wiki/DivmodPyflakes&quot;&gt;pyflakes&lt;/a&gt;. Last night, the magnificent &lt;a href=&quot;http://jcalderone.livejournal.com/&quot;&gt;Jean-Paul Calderone&lt;/a&gt; reviewed and landed my patch. This means that if you are using pyflakes trunk (either from Subversion &lt;a href=&quot;http://divmod.org/svn/Divmod/trunk/&quot;&gt;trunk&lt;/a&gt; or from the Launchpad &lt;a href=&quot;https://code.edge.launchpad.net/%7Evcs-imports/pyflakes/main&quot;&gt;Bazaar import&lt;/a&gt;), pyflakes will spot code like:&lt;br /&gt;&lt;pre&gt;&lt;b&gt;&lt;span class=&quot;code-lang&quot;&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span class=&quot;code-func&quot;&gt;foo&lt;/span&gt;&lt;/b&gt;(bar):&lt;br /&gt;baz = bar + 2&lt;br /&gt;&lt;b&gt;&lt;span class=&quot;code-lang&quot;&gt;return&lt;/span&gt;&lt;/b&gt; 12&lt;br /&gt;&lt;/pre&gt;and generate a warning like:&lt;br /&gt;&lt;pre&gt;example.py:2: local variable 'baz' is assigned to but never used&lt;br /&gt;&lt;/pre&gt;I use pyflakes hooked up to &lt;a href=&quot;http://www.emacswiki.org/emacs/FlyMake&quot;&gt;flymake&lt;/a&gt;, so it's always running all the time on every Python file I'm working on. Relying on it has become as second-nature as relying on syntax highlighting.  There's a whole class of mistakes I don't make any more, simply because it's on.&lt;br /&gt;&lt;br /&gt;However, the &lt;span style=&quot;font-style: italic;&quot;&gt;main&lt;/span&gt; way it helps me is when I'm refactoring code. When extracting a function or changing a variable name, pyflakes acts like a sort of todo list for me. Now that it shows unused local variables, it's getting dangerously close to perfect.&lt;br /&gt;&lt;br /&gt;To get pyflakes quickly, bzr branch &lt;a href=&quot;https://code.edge.launchpad.net/%7Evcs-imports/pyflakes/main&quot;&gt;lp:pyflakes&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;(Edit: Grammar fix)&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/5733547231775030285-8847071679260347539?l=code.mumak.net&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Wed, 03 Jun 2009 22:54:44 +0000</pubDate>
	<dc:creator>jml (noreply@blogger.com)</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: git merge conflict</title>
	<guid>http://thomas.apestaart.org/log/?p=898</guid>
	<link>http://thomas.apestaart.org/log/?p=898</link>
	<description>&lt;p&gt;For every &lt;a href=&quot;http://thomas.apestaart.org/log/?p=896&quot;&gt;positive experience with git&lt;/a&gt; there’s still more than enough negative ones to balance out.&lt;/p&gt;
&lt;p&gt;Today, I got into the situation where I was updating my gstreamer modules and one of them was apparently still in conflict.  Unhelpfully, git just says:&lt;br /&gt;
&lt;code&gt;You are in the middle of a conflicted merge.&lt;/code&gt;&lt;br /&gt;
without telling you what to do about it.&lt;/p&gt;
&lt;p&gt;Googling revealed lots of people in the same situation, and git reset –hard would work.  It looks like that would throw away my changes though.  Of course that’s one way out of the conflict.&lt;/p&gt;
&lt;p&gt;I want to know what the other way is - the one where you get a change to merge conflicts.&lt;/p&gt;
&lt;p&gt;Apparently the conflict was in a generated config file, so naively I deleted it because I wanted to check out that file again from the repository (probably an svn-ism that stuck with me).  I know that in this case I don’t actually need to be able to merge my changes, but I would like to know what would have been the correct way to get out of this situation.&lt;/p&gt;
&lt;p&gt;Here’s what I tried before I gave up and did a reset:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[gst-git] [thomas@level gst-plugins-ugly]$ git pull --rebase&lt;br /&gt;
You are in the middle of a conflicted merge.&lt;br /&gt;
[gst-git] [thomas@level gst-plugins-ugly]$ git diff&lt;br /&gt;
diff --cc win32/common/config.h&lt;br /&gt;
index 18dbcc4,abf941a..0000000&lt;br /&gt;
deleted file mode 100644,100644&lt;br /&gt;
-- a/win32/common/config.h&lt;br /&gt;
+++ /dev/null&lt;br /&gt;
[gst-git] [thomas@level gst-plugins-ugly]$ git checkout win32/common/config.h&lt;br /&gt;
error: path 'win32/common/config.h' is unmerged&lt;br /&gt;
[gst-git] [thomas@level gst-plugins-ugly]$ git reset -- win32/common/config.h&lt;br /&gt;
win32/common/config.h: locally modified&lt;/code&gt;&lt;/p&gt;</description>
	<pubDate>Tue, 02 Jun 2009 10:42:39 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Thomas Vander Stichele: git bisect</title>
	<guid>http://thomas.apestaart.org/log/?p=896</guid>
	<link>http://thomas.apestaart.org/log/?p=896</link>
	<description>&lt;p&gt;Today I finally had a reason to be happy about GStreamer having switched to GIT.&lt;/p&gt;
&lt;p&gt;I added actual encoding support to my CD ripper this weekend.  I’m only supporting lossless encoding for now.  Sadly, in practice it seems the FFMpeg ALAC encoder crashes, and the wavpack one hangs for me, so I’m left with .wav (meaning no compression) or .flac&lt;/p&gt;
&lt;p&gt;And then today I realized that some of my encoded .flac files had a strange bug in them.  I wasn’t sure where it was coming from, but some of my encoded files didn’t play with mplayer, gave an error when using flac -d, but still worked completely fine with GStreamer and totem.&lt;/p&gt;
&lt;p&gt;I first tried to find a different file from the GStreamer media testsuite to reproduce the symptom.  south.mp3 and benow.mp3 owrked fine, but sugar.ogg reproduced the problem.&lt;/p&gt;
&lt;p&gt;I also tried it with my installed version (0.10.8, while git master is at 0.10.15.1) and that worked fine.&lt;/p&gt;
&lt;p&gt;So that gave me two points to bisect inbetween.&lt;/p&gt;
&lt;p&gt;Then I read up on git bisect, and started playing with it.  It isn’t particularly nice to do by hand; most checkouts change enough of the autotools files that it has to rerun them most of the times.  Then configure changes win32/common/config.h which generates a local change.  The common submodule also gets in the way.  I got away with just compiling the flac plugin with make -C ext/flac before each test, so that sped up things.  But there’s definitely potential for human error.&lt;/p&gt;
&lt;p&gt;Basically, you start by doing git bisect start; git bisect bad; git checkout (known good commit); git bisect good&lt;/p&gt;
&lt;p&gt;This will leave you somewhere in the middle between the bad and the good commit.  Rebuild, do your test, then either type git bisect bad or git bisect good based on the test result.  Repeat until you’re at the last commit.&lt;/p&gt;
&lt;p&gt;That helped me find where the bug happened (see &lt;a href=&quot;http://bugzilla.gnome.org/show_bug.cgi?id=584455&quot;&gt;the bug report&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Of course I wondered immediately if I could automize this, since I wanted to make sure that the same commit broke my original files and I do not want to do that manual bisection again…&lt;/p&gt;
&lt;p&gt;It turns out you can; that’s what git bisect run is for.&lt;/p&gt;
&lt;p&gt;So, given the following two shell scripts:&lt;/p&gt;
&lt;p&gt;test.sh&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
#!/bin/bash&lt;/p&gt;
&lt;p&gt;git submodule update&lt;/p&gt;
&lt;p&gt;make -C ext/flac&lt;/p&gt;
&lt;p&gt;# rebuilds can touch these files leaving you with local changes&lt;br /&gt;
git checkout win32/common/config.h&lt;/p&gt;
&lt;p&gt;gst-launch -v filesrc location=/home/thomas/gst/media/medium/sugar.ogg ! oggdemux ! vorbisdec ! audioconvert ! audio/x-raw-int,width=16,depth=16 ! flacenc ! filesink location=test.flac&lt;br /&gt;
flac -d test.flac -f&lt;br /&gt;
# flac -d exits with 1 when it fails&lt;br /&gt;
exit $?
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;and bisect.sh:&lt;/p&gt;
&lt;p&gt;#!/bin/bash&lt;/p&gt;
&lt;p&gt;git bisect start&lt;br /&gt;
git bisect bad&lt;br /&gt;
# 0.10.8 release&lt;br /&gt;
git checkout c186d67f40827be349f97d810a45243c874b73f7&lt;br /&gt;
git bisect good&lt;br /&gt;
git bisect run ./test.sh&lt;/p&gt;
&lt;p&gt;I can now just run ./bisect.sh and it will do the whole process automatically.&lt;/p&gt;
&lt;p&gt;Try it if you’re curious on a checkout of gst-plugins-good. Change test.sh to point to your sugar.ogg file (which you can get from GStreamer’s test repository).  &lt;/p&gt;
&lt;p&gt;At the end, the output should show something like:&lt;br /&gt;
df707c666433a78d3878af6f055698d5756226c4 is first bad commit&lt;br /&gt;
commit df707c666433a78d3878af6f055698d5756226c4&lt;br /&gt;
Author: (HIDDEN TO PROTECT THE GUILTY)&lt;/p&gt;
&lt;p&gt;The ‘run’ command really is what makes the bisection useful for me.  Now, back to bug fixing….&lt;/p&gt;</description>
	<pubDate>Mon, 01 Jun 2009 15:46:07 +0000</pubDate>
	<dc:creator>Thomas</dc:creator>
</item>
<item>
	<title>Ralph Meijer: PubSubHubbub</title>
	<guid>http://ralphm.net/blog/2009/05/31/pubsubhubbub</guid>
	<link>http://ralphm.net/blog/2009/05/31/pubsubhubbub</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot;&gt;PubSubHubbub&lt;/a&gt; is
        a protocol and reference implementation for doing publish-subscribe
        using web hooks, polling in feeds triggered by a ping from the
        publisher, and POSTing Atom entries to notify subscribers. The
        notification part is similar to what I've been working on for the
        publish-subscribe stuff at Mediamatic Lab, where we spiced up &lt;a href=&quot;http://idavoll.ik.nu/&quot;&gt;Idavoll&lt;/a&gt; with an &lt;a href=&quot;http://idavoll.ik.nu/wiki/HTTP_Interface&quot;&gt;HTTP interface&lt;/a&gt;
        to bridge the gap between XMPP Publish-Subscribe and HTTP speaking
        entities.&lt;/p&gt;

      &lt;p&gt;Although I spend a lot of time working on XMPP based
        publish-subscribe, I understand the reasons for going for a full
        HTTP-based approach. XMPP can be intimidating for developers of web
        applications. While the differences between XMPP and HTTP are
        important (stateful connections, asynchronous processing, etc), the
        fact that it is different is reason often enough. Hosting
        facilities don't always offer ways to do XMPP, and there is not
        nearly enough running code out there to make it easier for people
        to play with these technologies to spice up their web application
        with non-IM XMPP functionality. Having platforms like Google App
        Engine provide sending and handling raw XMPP stanzas as part of the
        API would surely help.&lt;/p&gt;

      &lt;p&gt;That said, PubSubHubbub has two separate sides to it, the
        publishing part and the notification part. There's nothing that
        prevents a &lt;em&gt;hub&lt;/em&gt; to do the publishing part
        using regular XMPP publish-subscribe. Instead of fetching the Atom
        Feed over HTTP every time, it could use autodiscovery to find out
        the publish-subscribe node and upgrade by subscribing to it
        instead.  Similarly, the notification part could send out XMPP
        notifications.  Combined with existing HTTP aggregator, that
        combination is very similar to how the aggregator for &lt;a href=&quot;http://mimir.ik.nu/trac/&quot;&gt;Mimír&lt;/a&gt; works.&lt;/p&gt;

      &lt;p&gt;I'm still not convinced that PubSubHubbub is the answer to the
        efficient exchange of updates on social objects, but I do think it is a
        good way to make smaller entities be part of a federation of social
        networking sites. Likely, we'll see a hybrid approach, to begin
        with.&lt;/p&gt;</description>
	<pubDate>Sun, 31 May 2009 13:09:49 +0000</pubDate>
	<dc:creator>ralphm</dc:creator>
</item>

</channel>
</rss>
